@cloudbase/cloudbase-mcp 2.9.0 → 2.10.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 +3 -3
- package/dist/index.cjs +1404 -1658
- package/dist/index.js +1416 -1670
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -562,7 +562,7 @@ ${envIdSection}
|
|
|
562
562
|
## 环境信息
|
|
563
563
|
- 操作系统: ${os_1.default.type()} ${os_1.default.release()}
|
|
564
564
|
- Node.js版本: ${process.version}
|
|
565
|
-
- MCP 版本:${process.env.npm_package_version || "2.
|
|
565
|
+
- MCP 版本:${process.env.npm_package_version || "2.10.0" || 0}
|
|
566
566
|
- 系统架构: ${os_1.default.arch()}
|
|
567
567
|
- 时间: ${new Date().toISOString()}
|
|
568
568
|
- 请求ID: ${requestId}
|
|
@@ -5267,9 +5267,10 @@ checkIndex: 检查索引是否存在`),
|
|
|
5267
5267
|
title: "修改 NoSQL 数据库结构",
|
|
5268
5268
|
description: "修改 NoSQL 数据库结构",
|
|
5269
5269
|
inputSchema: {
|
|
5270
|
-
action: zod_1.z.enum(["createCollection", "updateCollection"])
|
|
5270
|
+
action: zod_1.z.enum(["createCollection", "updateCollection", "deleteCollection"])
|
|
5271
5271
|
.describe(`createCollection: 创建集合
|
|
5272
|
-
updateCollection:
|
|
5272
|
+
updateCollection: 更新集合
|
|
5273
|
+
deleteCollection: 删除集合`),
|
|
5273
5274
|
collectionName: zod_1.z.string().describe("集合名称"),
|
|
5274
5275
|
updateOptions: zod_1.z
|
|
5275
5276
|
.object({
|
|
@@ -5296,68 +5297,74 @@ updateCollection: 更新集合`),
|
|
|
5296
5297
|
},
|
|
5297
5298
|
annotations: {
|
|
5298
5299
|
readOnlyHint: false,
|
|
5299
|
-
destructiveHint:
|
|
5300
|
+
destructiveHint: true,
|
|
5300
5301
|
idempotentHint: false,
|
|
5301
5302
|
openWorldHint: true,
|
|
5302
5303
|
category: CATEGORY,
|
|
5303
5304
|
},
|
|
5304
5305
|
}, async ({ action, collectionName, updateOptions }) => {
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
|
|
5310
|
-
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
};
|
|
5323
|
-
}
|
|
5324
|
-
if (action === "updateCollection") {
|
|
5325
|
-
if (!updateOptions) {
|
|
5326
|
-
throw new Error("更新集合时必须提供 options");
|
|
5327
|
-
}
|
|
5328
|
-
const result = await cloudbase.database.updateCollection(collectionName, updateOptions);
|
|
5329
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
5330
|
-
return {
|
|
5331
|
-
content: [
|
|
5332
|
-
{
|
|
5333
|
-
type: "text",
|
|
5334
|
-
text: JSON.stringify({
|
|
5335
|
-
success: true,
|
|
5336
|
-
requestId: result.RequestId,
|
|
5337
|
-
action,
|
|
5338
|
-
message: "云开发数据库集合更新成功",
|
|
5339
|
-
}, null, 2),
|
|
5340
|
-
},
|
|
5341
|
-
],
|
|
5342
|
-
};
|
|
5343
|
-
}
|
|
5344
|
-
throw new Error(`不支持的操作类型: ${action}`);
|
|
5306
|
+
const cloudbase = await getManager();
|
|
5307
|
+
if (action === "createCollection") {
|
|
5308
|
+
const result = await cloudbase.database.createCollection(collectionName);
|
|
5309
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
5310
|
+
return {
|
|
5311
|
+
content: [
|
|
5312
|
+
{
|
|
5313
|
+
type: "text",
|
|
5314
|
+
text: JSON.stringify({
|
|
5315
|
+
success: true,
|
|
5316
|
+
requestId: result.RequestId,
|
|
5317
|
+
action,
|
|
5318
|
+
message: "云开发数据库集合创建成功",
|
|
5319
|
+
}, null, 2),
|
|
5320
|
+
},
|
|
5321
|
+
],
|
|
5322
|
+
};
|
|
5345
5323
|
}
|
|
5346
|
-
|
|
5324
|
+
if (action === "updateCollection") {
|
|
5325
|
+
if (!updateOptions) {
|
|
5326
|
+
throw new Error("更新集合时必须提供 options");
|
|
5327
|
+
}
|
|
5328
|
+
const result = await cloudbase.database.updateCollection(collectionName, updateOptions);
|
|
5329
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
5347
5330
|
return {
|
|
5348
5331
|
content: [
|
|
5349
5332
|
{
|
|
5350
5333
|
type: "text",
|
|
5351
5334
|
text: JSON.stringify({
|
|
5352
|
-
success:
|
|
5335
|
+
success: true,
|
|
5336
|
+
requestId: result.RequestId,
|
|
5353
5337
|
action,
|
|
5354
|
-
|
|
5355
|
-
message: "集合创建/更新操作失败",
|
|
5338
|
+
message: "云开发数据库集合更新成功",
|
|
5356
5339
|
}, null, 2),
|
|
5357
5340
|
},
|
|
5358
5341
|
],
|
|
5359
5342
|
};
|
|
5360
5343
|
}
|
|
5344
|
+
if (action === "deleteCollection") {
|
|
5345
|
+
const result = await cloudbase.database.deleteCollection(collectionName);
|
|
5346
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
5347
|
+
const body = {
|
|
5348
|
+
success: true,
|
|
5349
|
+
requestId: result.RequestId,
|
|
5350
|
+
action,
|
|
5351
|
+
message: result.Exists === false
|
|
5352
|
+
? "集合不存在"
|
|
5353
|
+
: "云开发数据库集合删除成功",
|
|
5354
|
+
};
|
|
5355
|
+
if (result.Exists === false) {
|
|
5356
|
+
body.exists = false;
|
|
5357
|
+
}
|
|
5358
|
+
return {
|
|
5359
|
+
content: [
|
|
5360
|
+
{
|
|
5361
|
+
type: "text",
|
|
5362
|
+
text: JSON.stringify(body, null, 2),
|
|
5363
|
+
},
|
|
5364
|
+
],
|
|
5365
|
+
};
|
|
5366
|
+
}
|
|
5367
|
+
throw new Error(`不支持的操作类型: ${action}`);
|
|
5361
5368
|
});
|
|
5362
5369
|
// readNoSqlDatabaseContent
|
|
5363
5370
|
server.registerTool?.("readNoSqlDatabaseContent", {
|
|
@@ -5386,53 +5393,36 @@ updateCollection: 更新集合`),
|
|
|
5386
5393
|
category: CATEGORY,
|
|
5387
5394
|
},
|
|
5388
5395
|
}, async ({ collectionName, query, projection, sort, limit, offset }) => {
|
|
5389
|
-
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
|
|
5403
|
-
|
|
5396
|
+
const cloudbase = await getManager();
|
|
5397
|
+
const instanceId = await getDatabaseInstanceId(getManager);
|
|
5398
|
+
const toJSONString = (v) => typeof v === "object" && v !== null ? JSON.stringify(v) : v;
|
|
5399
|
+
const result = await cloudbase.commonService("tcb", "2018-06-08").call({
|
|
5400
|
+
Action: "QueryRecords",
|
|
5401
|
+
Param: {
|
|
5402
|
+
TableName: collectionName,
|
|
5403
|
+
MgoQuery: toJSONString(query),
|
|
5404
|
+
MgoProjection: toJSONString(projection),
|
|
5405
|
+
MgoSort: toJSONString(sort),
|
|
5406
|
+
MgoLimit: limit ?? 100,
|
|
5407
|
+
MgoOffset: offset,
|
|
5408
|
+
Tag: instanceId,
|
|
5409
|
+
},
|
|
5410
|
+
});
|
|
5411
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
5412
|
+
return {
|
|
5413
|
+
content: [
|
|
5414
|
+
{
|
|
5415
|
+
type: "text",
|
|
5416
|
+
text: JSON.stringify({
|
|
5417
|
+
success: true,
|
|
5418
|
+
requestId: result.RequestId,
|
|
5419
|
+
data: result.Data,
|
|
5420
|
+
pager: result.Pager,
|
|
5421
|
+
message: "文档查询成功",
|
|
5422
|
+
}, null, 2),
|
|
5404
5423
|
},
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
return {
|
|
5408
|
-
content: [
|
|
5409
|
-
{
|
|
5410
|
-
type: "text",
|
|
5411
|
-
text: JSON.stringify({
|
|
5412
|
-
success: true,
|
|
5413
|
-
requestId: result.RequestId,
|
|
5414
|
-
data: result.Data,
|
|
5415
|
-
pager: result.Pager,
|
|
5416
|
-
message: "文档查询成功",
|
|
5417
|
-
}, null, 2),
|
|
5418
|
-
},
|
|
5419
|
-
],
|
|
5420
|
-
};
|
|
5421
|
-
}
|
|
5422
|
-
catch (error) {
|
|
5423
|
-
return {
|
|
5424
|
-
content: [
|
|
5425
|
-
{
|
|
5426
|
-
type: "text",
|
|
5427
|
-
text: JSON.stringify({
|
|
5428
|
-
success: false,
|
|
5429
|
-
error: error.message,
|
|
5430
|
-
message: "文档查询失败",
|
|
5431
|
-
}, null, 2),
|
|
5432
|
-
},
|
|
5433
|
-
],
|
|
5434
|
-
};
|
|
5435
|
-
}
|
|
5424
|
+
],
|
|
5425
|
+
};
|
|
5436
5426
|
});
|
|
5437
5427
|
// writeNoSqlDatabaseContent
|
|
5438
5428
|
server.registerTool?.("writeNoSqlDatabaseContent", {
|
|
@@ -5440,9 +5430,7 @@ updateCollection: 更新集合`),
|
|
|
5440
5430
|
description: "修改 NoSQL 数据库数据记录",
|
|
5441
5431
|
inputSchema: {
|
|
5442
5432
|
action: zod_1.z.enum(["insert", "update", "delete"])
|
|
5443
|
-
.describe(`
|
|
5444
|
-
updateCollection: 更新数据
|
|
5445
|
-
deleteCollection: 删除数据`),
|
|
5433
|
+
.describe(`insert: 插入数据(新增文档)\nupdate: 更新数据\ndelete: 删除数据`),
|
|
5446
5434
|
collectionName: zod_1.z.string().describe("集合名称"),
|
|
5447
5435
|
documents: zod_1.z
|
|
5448
5436
|
.array(zod_1.z.object({}).passthrough())
|
|
@@ -5541,98 +5529,70 @@ deleteCollection: 删除数据`),
|
|
|
5541
5529
|
});
|
|
5542
5530
|
}
|
|
5543
5531
|
async function insertDocuments({ collectionName, documents, getManager, logger, }) {
|
|
5544
|
-
|
|
5545
|
-
|
|
5546
|
-
|
|
5547
|
-
|
|
5548
|
-
|
|
5549
|
-
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
|
|
5562
|
-
message: "文档插入成功",
|
|
5563
|
-
}, null, 2);
|
|
5564
|
-
}
|
|
5565
|
-
catch (error) {
|
|
5566
|
-
return JSON.stringify({
|
|
5567
|
-
success: false,
|
|
5568
|
-
error: error.message,
|
|
5569
|
-
message: "文档插入失败",
|
|
5570
|
-
}, null, 2);
|
|
5571
|
-
}
|
|
5532
|
+
const cloudbase = await getManager();
|
|
5533
|
+
const instanceId = await getDatabaseInstanceId(getManager);
|
|
5534
|
+
const docsAsStrings = documents.map((doc) => JSON.stringify(doc));
|
|
5535
|
+
const result = await cloudbase.commonService("tcb", "2018-06-08").call({
|
|
5536
|
+
Action: "PutItem",
|
|
5537
|
+
Param: {
|
|
5538
|
+
TableName: collectionName,
|
|
5539
|
+
MgoDocs: docsAsStrings,
|
|
5540
|
+
Tag: instanceId,
|
|
5541
|
+
},
|
|
5542
|
+
});
|
|
5543
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(logger, result);
|
|
5544
|
+
return JSON.stringify({
|
|
5545
|
+
success: true,
|
|
5546
|
+
requestId: result.RequestId,
|
|
5547
|
+
insertedIds: result.InsertedIds,
|
|
5548
|
+
message: "文档插入成功",
|
|
5549
|
+
}, null, 2);
|
|
5572
5550
|
}
|
|
5573
5551
|
async function updateDocuments({ collectionName, query, update, isMulti, upsert, getManager, logger, }) {
|
|
5574
|
-
|
|
5575
|
-
|
|
5576
|
-
|
|
5577
|
-
|
|
5578
|
-
|
|
5579
|
-
|
|
5580
|
-
|
|
5581
|
-
|
|
5582
|
-
|
|
5583
|
-
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
|
|
5588
|
-
|
|
5589
|
-
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
}, null, 2);
|
|
5598
|
-
}
|
|
5599
|
-
catch (error) {
|
|
5600
|
-
return JSON.stringify({
|
|
5601
|
-
success: false,
|
|
5602
|
-
error: error.message,
|
|
5603
|
-
message: "文档更新失败",
|
|
5604
|
-
}, null, 2);
|
|
5605
|
-
}
|
|
5552
|
+
const cloudbase = await getManager();
|
|
5553
|
+
const instanceId = await getDatabaseInstanceId(getManager);
|
|
5554
|
+
const toJSONString = (v) => typeof v === "object" && v !== null ? JSON.stringify(v) : v;
|
|
5555
|
+
const result = await cloudbase.commonService("tcb", "2018-06-08").call({
|
|
5556
|
+
Action: "UpdateItem",
|
|
5557
|
+
Param: {
|
|
5558
|
+
TableName: collectionName,
|
|
5559
|
+
MgoQuery: toJSONString(query),
|
|
5560
|
+
MgoUpdate: toJSONString(update),
|
|
5561
|
+
MgoIsMulti: isMulti,
|
|
5562
|
+
MgoUpsert: upsert,
|
|
5563
|
+
Tag: instanceId,
|
|
5564
|
+
},
|
|
5565
|
+
});
|
|
5566
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(logger, result);
|
|
5567
|
+
return JSON.stringify({
|
|
5568
|
+
success: true,
|
|
5569
|
+
requestId: result.RequestId,
|
|
5570
|
+
modifiedCount: result.ModifiedNum,
|
|
5571
|
+
matchedCount: result.MatchedNum,
|
|
5572
|
+
upsertedId: result.UpsertedId,
|
|
5573
|
+
message: "文档更新成功",
|
|
5574
|
+
}, null, 2);
|
|
5606
5575
|
}
|
|
5607
5576
|
async function deleteDocuments({ collectionName, query, isMulti, getManager, logger, }) {
|
|
5608
|
-
|
|
5609
|
-
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
|
|
5614
|
-
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
|
|
5627
|
-
}, null, 2);
|
|
5628
|
-
}
|
|
5629
|
-
catch (error) {
|
|
5630
|
-
return JSON.stringify({
|
|
5631
|
-
success: false,
|
|
5632
|
-
error: error.message,
|
|
5633
|
-
message: "文档删除失败",
|
|
5634
|
-
}, null, 2);
|
|
5635
|
-
}
|
|
5577
|
+
const cloudbase = await getManager();
|
|
5578
|
+
const instanceId = await getDatabaseInstanceId(getManager);
|
|
5579
|
+
const toJSONString = (v) => typeof v === "object" && v !== null ? JSON.stringify(v) : v;
|
|
5580
|
+
const result = await cloudbase.commonService("tcb", "2018-06-08").call({
|
|
5581
|
+
Action: "DeleteItem",
|
|
5582
|
+
Param: {
|
|
5583
|
+
TableName: collectionName,
|
|
5584
|
+
MgoQuery: toJSONString(query),
|
|
5585
|
+
MgoIsMulti: isMulti,
|
|
5586
|
+
Tag: instanceId,
|
|
5587
|
+
},
|
|
5588
|
+
});
|
|
5589
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(logger, result);
|
|
5590
|
+
return JSON.stringify({
|
|
5591
|
+
success: true,
|
|
5592
|
+
requestId: result.RequestId,
|
|
5593
|
+
deleted: result.Deleted,
|
|
5594
|
+
message: "文档删除成功",
|
|
5595
|
+
}, null, 2);
|
|
5636
5596
|
}
|
|
5637
5597
|
|
|
5638
5598
|
|
|
@@ -6202,289 +6162,271 @@ function registerDataModelTools(server) {
|
|
|
6202
6162
|
category: "database",
|
|
6203
6163
|
},
|
|
6204
6164
|
}, async ({ action, name, names, }) => {
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
|
|
6209
|
-
|
|
6210
|
-
|
|
6211
|
-
|
|
6212
|
-
|
|
6213
|
-
|
|
6214
|
-
|
|
6215
|
-
|
|
6216
|
-
|
|
6217
|
-
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
|
|
6221
|
-
|
|
6222
|
-
|
|
6223
|
-
|
|
6224
|
-
|
|
6225
|
-
|
|
6226
|
-
|
|
6227
|
-
|
|
6228
|
-
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6240
|
-
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
|
|
6244
|
-
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
};
|
|
6254
|
-
}
|
|
6255
|
-
catch (e) {
|
|
6256
|
-
simplifiedSchema = { error: "Schema解析失败" };
|
|
6257
|
-
}
|
|
6165
|
+
const cloudbase = await getManager();
|
|
6166
|
+
let currentEnvId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
6167
|
+
let result;
|
|
6168
|
+
switch (action) {
|
|
6169
|
+
case "get":
|
|
6170
|
+
if (!name) {
|
|
6171
|
+
throw new Error("获取数据模型需要提供模型名称");
|
|
6172
|
+
}
|
|
6173
|
+
try {
|
|
6174
|
+
result = await cloudbase.commonService("lowcode").call({
|
|
6175
|
+
Action: "DescribeBasicDataSource",
|
|
6176
|
+
Param: {
|
|
6177
|
+
EnvId: currentEnvId,
|
|
6178
|
+
Name: name,
|
|
6179
|
+
},
|
|
6180
|
+
});
|
|
6181
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
6182
|
+
// 只保留基础字段,过滤掉冗余信息,并简化Schema
|
|
6183
|
+
let simplifiedSchema = null;
|
|
6184
|
+
// 解析并简化Schema
|
|
6185
|
+
if (result.Data.Schema) {
|
|
6186
|
+
try {
|
|
6187
|
+
const schema = JSON.parse(result.Data.Schema);
|
|
6188
|
+
const properties = schema.properties || {};
|
|
6189
|
+
// 提取用户定义的字段(排除系统字段)
|
|
6190
|
+
const userFields = Object.keys(properties)
|
|
6191
|
+
.filter((key) => !properties[key]["x-system"]) // 排除系统字段
|
|
6192
|
+
.map((key) => {
|
|
6193
|
+
const field = properties[key];
|
|
6194
|
+
return parseFieldStructure(field, key, schema);
|
|
6195
|
+
});
|
|
6196
|
+
// 提取关联关系
|
|
6197
|
+
const relations = userFields
|
|
6198
|
+
.filter((field) => field.linkage)
|
|
6199
|
+
.map((field) => ({
|
|
6200
|
+
field: field.name,
|
|
6201
|
+
type: field.format,
|
|
6202
|
+
title: field.title,
|
|
6203
|
+
targetModel: field.linkage.parentDataSourceName,
|
|
6204
|
+
foreignKey: field.linkage.parentFieldKey,
|
|
6205
|
+
displayField: field.linkage.parentFieldTitle,
|
|
6206
|
+
}));
|
|
6207
|
+
simplifiedSchema = {
|
|
6208
|
+
userFields,
|
|
6209
|
+
relations,
|
|
6210
|
+
totalFields: Object.keys(properties).length,
|
|
6211
|
+
userFieldsCount: userFields.length,
|
|
6212
|
+
};
|
|
6258
6213
|
}
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
|
|
6262
|
-
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
|
|
6266
|
-
|
|
6267
|
-
|
|
6268
|
-
|
|
6269
|
-
|
|
6270
|
-
|
|
6271
|
-
|
|
6272
|
-
|
|
6273
|
-
|
|
6274
|
-
|
|
6275
|
-
|
|
6276
|
-
|
|
6277
|
-
|
|
6278
|
-
|
|
6279
|
-
|
|
6280
|
-
|
|
6281
|
-
|
|
6282
|
-
|
|
6283
|
-
|
|
6284
|
-
|
|
6285
|
-
|
|
6286
|
-
|
|
6287
|
-
|
|
6288
|
-
|
|
6289
|
-
}
|
|
6290
|
-
}
|
|
6291
|
-
|
|
6292
|
-
|
|
6214
|
+
catch (e) {
|
|
6215
|
+
simplifiedSchema = { error: "Schema解析失败" };
|
|
6216
|
+
}
|
|
6217
|
+
}
|
|
6218
|
+
// 尝试生成Mermaid图表
|
|
6219
|
+
let mermaidDiagram = null;
|
|
6220
|
+
if (result.Data.Schema &&
|
|
6221
|
+
jsonSchemaToMermaid &&
|
|
6222
|
+
simplifiedSchema &&
|
|
6223
|
+
!simplifiedSchema.error) {
|
|
6224
|
+
try {
|
|
6225
|
+
const mainSchema = JSON.parse(result.Data.Schema);
|
|
6226
|
+
const schemasMap = {
|
|
6227
|
+
[name]: mainSchema,
|
|
6228
|
+
};
|
|
6229
|
+
// 获取关联模型的 schema
|
|
6230
|
+
if (simplifiedSchema.relations &&
|
|
6231
|
+
simplifiedSchema.relations.length > 0) {
|
|
6232
|
+
const relatedModelNames = [
|
|
6233
|
+
...new Set(simplifiedSchema.relations.map((rel) => rel.targetModel)),
|
|
6234
|
+
];
|
|
6235
|
+
for (const relatedModelName of relatedModelNames) {
|
|
6236
|
+
try {
|
|
6237
|
+
const relatedResult = await cloudbase
|
|
6238
|
+
.commonService("lowcode")
|
|
6239
|
+
.call({
|
|
6240
|
+
Action: "DescribeBasicDataSource",
|
|
6241
|
+
Param: {
|
|
6242
|
+
EnvId: currentEnvId,
|
|
6243
|
+
Name: relatedModelName,
|
|
6244
|
+
},
|
|
6245
|
+
});
|
|
6246
|
+
if (relatedResult.Data && relatedResult.Data.Schema) {
|
|
6247
|
+
schemasMap[relatedModelName] = JSON.parse(relatedResult.Data.Schema);
|
|
6293
6248
|
}
|
|
6294
6249
|
}
|
|
6250
|
+
catch (e) {
|
|
6251
|
+
console.warn(`获取关联模型 ${relatedModelName} 的 schema 失败:`, e);
|
|
6252
|
+
}
|
|
6295
6253
|
}
|
|
6296
|
-
// 调用 jsonSchemaToMermaid,传入正确的参数格式
|
|
6297
|
-
mermaidDiagram = jsonSchemaToMermaid(schemasMap);
|
|
6298
|
-
}
|
|
6299
|
-
catch (e) {
|
|
6300
|
-
console.warn("生成Mermaid图表失败:", e);
|
|
6301
6254
|
}
|
|
6255
|
+
// 调用 jsonSchemaToMermaid,传入正确的参数格式
|
|
6256
|
+
mermaidDiagram = jsonSchemaToMermaid(schemasMap);
|
|
6302
6257
|
}
|
|
6303
|
-
|
|
6304
|
-
|
|
6305
|
-
Title: result.Data.Title,
|
|
6306
|
-
Description: result.Data.Description,
|
|
6307
|
-
Name: result.Data.Name,
|
|
6308
|
-
UpdatedAt: result.Data.UpdatedAt,
|
|
6309
|
-
Schema: simplifiedSchema,
|
|
6310
|
-
mermaid: mermaidDiagram,
|
|
6311
|
-
};
|
|
6312
|
-
return {
|
|
6313
|
-
content: [
|
|
6314
|
-
{
|
|
6315
|
-
type: "text",
|
|
6316
|
-
text: JSON.stringify({
|
|
6317
|
-
success: true,
|
|
6318
|
-
action: "get",
|
|
6319
|
-
data: simplifiedModel,
|
|
6320
|
-
message: "获取数据模型成功",
|
|
6321
|
-
}, null, 2),
|
|
6322
|
-
},
|
|
6323
|
-
],
|
|
6324
|
-
};
|
|
6325
|
-
}
|
|
6326
|
-
catch (error) {
|
|
6327
|
-
if (error.original?.Code === "ResourceNotFound") {
|
|
6328
|
-
return {
|
|
6329
|
-
content: [
|
|
6330
|
-
{
|
|
6331
|
-
type: "text",
|
|
6332
|
-
text: JSON.stringify({
|
|
6333
|
-
success: false,
|
|
6334
|
-
action: "get",
|
|
6335
|
-
error: "ResourceNotFound",
|
|
6336
|
-
message: `数据模型 ${name} 不存在`,
|
|
6337
|
-
}, null, 2),
|
|
6338
|
-
},
|
|
6339
|
-
],
|
|
6340
|
-
};
|
|
6258
|
+
catch (e) {
|
|
6259
|
+
console.warn("生成Mermaid图表失败:", e);
|
|
6341
6260
|
}
|
|
6342
|
-
throw error;
|
|
6343
6261
|
}
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
|
|
6347
|
-
|
|
6348
|
-
|
|
6349
|
-
|
|
6350
|
-
|
|
6351
|
-
|
|
6262
|
+
const simplifiedModel = {
|
|
6263
|
+
DbInstanceType: result.Data.DbInstanceType,
|
|
6264
|
+
Title: result.Data.Title,
|
|
6265
|
+
Description: result.Data.Description,
|
|
6266
|
+
Name: result.Data.Name,
|
|
6267
|
+
UpdatedAt: result.Data.UpdatedAt,
|
|
6268
|
+
Schema: simplifiedSchema,
|
|
6269
|
+
mermaid: mermaidDiagram,
|
|
6352
6270
|
};
|
|
6353
|
-
// 只有当 names 参数存在且不为空时才添加过滤条件
|
|
6354
|
-
if (names && names.length > 0) {
|
|
6355
|
-
listParams.DataSourceNames = names;
|
|
6356
|
-
}
|
|
6357
|
-
result = await cloudbase.commonService("lowcode").call({
|
|
6358
|
-
Action: "DescribeDataSourceList",
|
|
6359
|
-
Param: listParams,
|
|
6360
|
-
});
|
|
6361
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
6362
|
-
const models = result.Data?.Rows || [];
|
|
6363
|
-
// 只保留基础字段,list操作不返回Schema
|
|
6364
|
-
const simplifiedModels = models.map((model) => ({
|
|
6365
|
-
DbInstanceType: model.DbInstanceType,
|
|
6366
|
-
Title: model.Title,
|
|
6367
|
-
Description: model.Description,
|
|
6368
|
-
Name: model.Name,
|
|
6369
|
-
UpdatedAt: model.UpdatedAt,
|
|
6370
|
-
}));
|
|
6371
6271
|
return {
|
|
6372
6272
|
content: [
|
|
6373
6273
|
{
|
|
6374
6274
|
type: "text",
|
|
6375
6275
|
text: JSON.stringify({
|
|
6376
6276
|
success: true,
|
|
6377
|
-
action: "
|
|
6378
|
-
data:
|
|
6379
|
-
|
|
6380
|
-
message: "获取数据模型列表成功",
|
|
6277
|
+
action: "get",
|
|
6278
|
+
data: simplifiedModel,
|
|
6279
|
+
message: "获取数据模型成功",
|
|
6381
6280
|
}, null, 2),
|
|
6382
6281
|
},
|
|
6383
6282
|
],
|
|
6384
6283
|
};
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
}
|
|
6389
|
-
try {
|
|
6390
|
-
// 先获取模型信息
|
|
6391
|
-
result = await cloudbase.commonService("lowcode").call({
|
|
6392
|
-
Action: "DescribeBasicDataSource",
|
|
6393
|
-
Param: {
|
|
6394
|
-
EnvId: currentEnvId,
|
|
6395
|
-
Name: name,
|
|
6396
|
-
},
|
|
6397
|
-
});
|
|
6398
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
6399
|
-
if (!result.Data) {
|
|
6400
|
-
throw new Error(`数据模型 ${name} 不存在`);
|
|
6401
|
-
}
|
|
6402
|
-
// 解析Schema获取字段信息
|
|
6403
|
-
let userFields = [];
|
|
6404
|
-
let relations = [];
|
|
6405
|
-
if (result.Data.Schema) {
|
|
6406
|
-
try {
|
|
6407
|
-
const schema = JSON.parse(result.Data.Schema);
|
|
6408
|
-
const properties = schema.properties || {};
|
|
6409
|
-
// 提取用户定义的字段
|
|
6410
|
-
userFields = Object.keys(properties)
|
|
6411
|
-
.filter((key) => !properties[key]["x-system"])
|
|
6412
|
-
.map((key) => {
|
|
6413
|
-
const field = properties[key];
|
|
6414
|
-
return parseFieldStructure(field, key, schema);
|
|
6415
|
-
});
|
|
6416
|
-
// 提取关联关系
|
|
6417
|
-
relations = userFields
|
|
6418
|
-
.filter((field) => field.linkage)
|
|
6419
|
-
.map((field) => ({
|
|
6420
|
-
field: field.name,
|
|
6421
|
-
type: field.format,
|
|
6422
|
-
title: field.title,
|
|
6423
|
-
targetModel: field.linkage.parentDataSourceName,
|
|
6424
|
-
foreignKey: field.linkage.parentFieldKey,
|
|
6425
|
-
displayField: field.linkage.parentFieldTitle,
|
|
6426
|
-
}));
|
|
6427
|
-
}
|
|
6428
|
-
catch (e) {
|
|
6429
|
-
// Schema解析失败,使用空数组
|
|
6430
|
-
console.error("Schema解析失败", e);
|
|
6431
|
-
}
|
|
6432
|
-
}
|
|
6433
|
-
// 生成SDK使用文档
|
|
6434
|
-
const docs = generateSDKDocs(result.Data.Name, result.Data.Title, userFields, relations);
|
|
6284
|
+
}
|
|
6285
|
+
catch (error) {
|
|
6286
|
+
if (error.original?.Code === "ResourceNotFound") {
|
|
6435
6287
|
return {
|
|
6436
6288
|
content: [
|
|
6437
6289
|
{
|
|
6438
6290
|
type: "text",
|
|
6439
6291
|
text: JSON.stringify({
|
|
6440
|
-
success:
|
|
6441
|
-
action: "
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
docs,
|
|
6445
|
-
message: "SDK使用文档生成成功",
|
|
6292
|
+
success: false,
|
|
6293
|
+
action: "get",
|
|
6294
|
+
error: "ResourceNotFound",
|
|
6295
|
+
message: `数据模型 ${name} 不存在`,
|
|
6446
6296
|
}, null, 2),
|
|
6447
6297
|
},
|
|
6448
6298
|
],
|
|
6449
6299
|
};
|
|
6450
6300
|
}
|
|
6451
|
-
|
|
6452
|
-
|
|
6453
|
-
|
|
6454
|
-
|
|
6455
|
-
|
|
6456
|
-
|
|
6457
|
-
|
|
6458
|
-
|
|
6459
|
-
|
|
6460
|
-
|
|
6461
|
-
|
|
6462
|
-
|
|
6463
|
-
|
|
6464
|
-
|
|
6465
|
-
|
|
6301
|
+
throw error;
|
|
6302
|
+
}
|
|
6303
|
+
case "list":
|
|
6304
|
+
// 构建请求参数
|
|
6305
|
+
const listParams = {
|
|
6306
|
+
EnvId: currentEnvId,
|
|
6307
|
+
PageIndex: 1,
|
|
6308
|
+
PageSize: 1000,
|
|
6309
|
+
QuerySystemModel: true, // 查询系统模型
|
|
6310
|
+
QueryConnector: 0, // 0 表示数据模型
|
|
6311
|
+
};
|
|
6312
|
+
// 只有当 names 参数存在且不为空时才添加过滤条件
|
|
6313
|
+
if (names && names.length > 0) {
|
|
6314
|
+
listParams.DataSourceNames = names;
|
|
6315
|
+
}
|
|
6316
|
+
result = await cloudbase.commonService("lowcode").call({
|
|
6317
|
+
Action: "DescribeDataSourceList",
|
|
6318
|
+
Param: listParams,
|
|
6319
|
+
});
|
|
6320
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
6321
|
+
const models = result.Data?.Rows || [];
|
|
6322
|
+
// 只保留基础字段,list操作不返回Schema
|
|
6323
|
+
const simplifiedModels = models.map((model) => ({
|
|
6324
|
+
DbInstanceType: model.DbInstanceType,
|
|
6325
|
+
Title: model.Title,
|
|
6326
|
+
Description: model.Description,
|
|
6327
|
+
Name: model.Name,
|
|
6328
|
+
UpdatedAt: model.UpdatedAt,
|
|
6329
|
+
}));
|
|
6330
|
+
return {
|
|
6331
|
+
content: [
|
|
6332
|
+
{
|
|
6333
|
+
type: "text",
|
|
6334
|
+
text: JSON.stringify({
|
|
6335
|
+
success: true,
|
|
6336
|
+
action: "list",
|
|
6337
|
+
data: simplifiedModels,
|
|
6338
|
+
count: simplifiedModels.length,
|
|
6339
|
+
message: "获取数据模型列表成功",
|
|
6340
|
+
}, null, 2),
|
|
6341
|
+
},
|
|
6342
|
+
],
|
|
6343
|
+
};
|
|
6344
|
+
case "docs":
|
|
6345
|
+
if (!name) {
|
|
6346
|
+
throw new Error("生成SDK文档需要提供模型名称");
|
|
6347
|
+
}
|
|
6348
|
+
try {
|
|
6349
|
+
// 先获取模型信息
|
|
6350
|
+
result = await cloudbase.commonService("lowcode").call({
|
|
6351
|
+
Action: "DescribeBasicDataSource",
|
|
6352
|
+
Param: {
|
|
6353
|
+
EnvId: currentEnvId,
|
|
6354
|
+
Name: name,
|
|
6355
|
+
},
|
|
6356
|
+
});
|
|
6357
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
6358
|
+
if (!result.Data) {
|
|
6359
|
+
throw new Error(`数据模型 ${name} 不存在`);
|
|
6360
|
+
}
|
|
6361
|
+
// 解析Schema获取字段信息
|
|
6362
|
+
let userFields = [];
|
|
6363
|
+
let relations = [];
|
|
6364
|
+
if (result.Data.Schema) {
|
|
6365
|
+
try {
|
|
6366
|
+
const schema = JSON.parse(result.Data.Schema);
|
|
6367
|
+
const properties = schema.properties || {};
|
|
6368
|
+
// 提取用户定义的字段
|
|
6369
|
+
userFields = Object.keys(properties)
|
|
6370
|
+
.filter((key) => !properties[key]["x-system"])
|
|
6371
|
+
.map((key) => {
|
|
6372
|
+
const field = properties[key];
|
|
6373
|
+
return parseFieldStructure(field, key, schema);
|
|
6374
|
+
});
|
|
6375
|
+
// 提取关联关系
|
|
6376
|
+
relations = userFields
|
|
6377
|
+
.filter((field) => field.linkage)
|
|
6378
|
+
.map((field) => ({
|
|
6379
|
+
field: field.name,
|
|
6380
|
+
type: field.format,
|
|
6381
|
+
title: field.title,
|
|
6382
|
+
targetModel: field.linkage.parentDataSourceName,
|
|
6383
|
+
foreignKey: field.linkage.parentFieldKey,
|
|
6384
|
+
displayField: field.linkage.parentFieldTitle,
|
|
6385
|
+
}));
|
|
6386
|
+
}
|
|
6387
|
+
catch (e) {
|
|
6388
|
+
// Schema解析失败,使用空数组
|
|
6389
|
+
console.error("Schema解析失败", e);
|
|
6466
6390
|
}
|
|
6467
|
-
throw error;
|
|
6468
6391
|
}
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
}
|
|
6486
|
-
|
|
6487
|
-
|
|
6392
|
+
// 生成SDK使用文档
|
|
6393
|
+
const docs = generateSDKDocs(result.Data.Name, result.Data.Title, userFields, relations);
|
|
6394
|
+
return {
|
|
6395
|
+
content: [
|
|
6396
|
+
{
|
|
6397
|
+
type: "text",
|
|
6398
|
+
text: JSON.stringify({
|
|
6399
|
+
success: true,
|
|
6400
|
+
action: "docs",
|
|
6401
|
+
modelName: name,
|
|
6402
|
+
modelTitle: result.Data.Title,
|
|
6403
|
+
docs,
|
|
6404
|
+
message: "SDK使用文档生成成功",
|
|
6405
|
+
}, null, 2),
|
|
6406
|
+
},
|
|
6407
|
+
],
|
|
6408
|
+
};
|
|
6409
|
+
}
|
|
6410
|
+
catch (error) {
|
|
6411
|
+
if (error.original?.Code === "ResourceNotFound") {
|
|
6412
|
+
return {
|
|
6413
|
+
content: [
|
|
6414
|
+
{
|
|
6415
|
+
type: "text",
|
|
6416
|
+
text: JSON.stringify({
|
|
6417
|
+
success: false,
|
|
6418
|
+
action: "docs",
|
|
6419
|
+
error: "ResourceNotFound",
|
|
6420
|
+
message: `数据模型 ${name} 不存在`,
|
|
6421
|
+
}, null, 2),
|
|
6422
|
+
},
|
|
6423
|
+
],
|
|
6424
|
+
};
|
|
6425
|
+
}
|
|
6426
|
+
throw error;
|
|
6427
|
+
}
|
|
6428
|
+
default:
|
|
6429
|
+
throw new Error(`不支持的操作类型: ${action}`);
|
|
6488
6430
|
}
|
|
6489
6431
|
});
|
|
6490
6432
|
// modifyDataModel - 数据模型修改工具(创建/更新)
|
|
@@ -6557,126 +6499,108 @@ classDiagram
|
|
|
6557
6499
|
category: "database",
|
|
6558
6500
|
},
|
|
6559
6501
|
}, async ({ mermaidDiagram, action = "create", publish = false, dbInstanceType = "MYSQL", }) => {
|
|
6560
|
-
|
|
6561
|
-
|
|
6562
|
-
|
|
6563
|
-
|
|
6564
|
-
const schemas = mermaidToJsonSchema(mermaidDiagram);
|
|
6565
|
-
if (!schemas || Object.keys(schemas).length === 0) {
|
|
6566
|
-
return {
|
|
6567
|
-
content: [
|
|
6568
|
-
{
|
|
6569
|
-
type: "text",
|
|
6570
|
-
text: JSON.stringify({
|
|
6571
|
-
success: false,
|
|
6572
|
-
error: "No schemas generated from Mermaid diagram",
|
|
6573
|
-
message: "无法从Mermaid图表生成数据模型Schema",
|
|
6574
|
-
}, null, 2),
|
|
6575
|
-
},
|
|
6576
|
-
],
|
|
6577
|
-
};
|
|
6578
|
-
}
|
|
6579
|
-
// 创建数据模型列表
|
|
6580
|
-
const createDataModelList = Object.entries(schemas).map(([name, schema]) => {
|
|
6581
|
-
return {
|
|
6582
|
-
CreateSource: "cloudbase_create",
|
|
6583
|
-
Creator: null,
|
|
6584
|
-
DbLinkName: null,
|
|
6585
|
-
Description: schema.description ||
|
|
6586
|
-
`${schema.title || name}数据模型`,
|
|
6587
|
-
Schema: JSON.stringify(createBackendSchemaParams(schema)),
|
|
6588
|
-
Title: schema.title || name,
|
|
6589
|
-
Name: name,
|
|
6590
|
-
TableNameRule: "only_name",
|
|
6591
|
-
};
|
|
6592
|
-
});
|
|
6593
|
-
// 调用批量创建数据模型API
|
|
6594
|
-
const result = await cloudbase.commonService("lowcode").call({
|
|
6595
|
-
Action: "BatchCreateDataModelList",
|
|
6596
|
-
Param: {
|
|
6597
|
-
CreateDataModelList: createDataModelList,
|
|
6598
|
-
Creator: null,
|
|
6599
|
-
DbInstanceType: dbInstanceType,
|
|
6600
|
-
EnvId: currentEnvId,
|
|
6601
|
-
},
|
|
6602
|
-
});
|
|
6603
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
6604
|
-
const taskId = result.Data?.TaskId;
|
|
6605
|
-
if (!taskId) {
|
|
6606
|
-
return {
|
|
6607
|
-
content: [
|
|
6608
|
-
{
|
|
6609
|
-
type: "text",
|
|
6610
|
-
text: JSON.stringify({
|
|
6611
|
-
success: false,
|
|
6612
|
-
requestId: result.RequestId,
|
|
6613
|
-
error: "No TaskId returned",
|
|
6614
|
-
message: "创建任务失败,未返回任务ID",
|
|
6615
|
-
}, null, 2),
|
|
6616
|
-
},
|
|
6617
|
-
],
|
|
6618
|
-
};
|
|
6619
|
-
}
|
|
6620
|
-
// 轮询任务状态直至完成或超时
|
|
6621
|
-
const maxWaitTime = 30000; // 30秒超时
|
|
6622
|
-
const startTime = Date.now();
|
|
6623
|
-
let status = "init";
|
|
6624
|
-
let statusResult = null;
|
|
6625
|
-
while (status === "init" && Date.now() - startTime < maxWaitTime) {
|
|
6626
|
-
await new Promise((resolve) => setTimeout(resolve, 2000)); // 等待2秒
|
|
6627
|
-
statusResult = await cloudbase.commonService("lowcode").call({
|
|
6628
|
-
Action: "QueryModelTaskStatus",
|
|
6629
|
-
Param: {
|
|
6630
|
-
EnvId: currentEnvId,
|
|
6631
|
-
TaskId: taskId,
|
|
6632
|
-
},
|
|
6633
|
-
});
|
|
6634
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, statusResult);
|
|
6635
|
-
status = statusResult.Data?.Status || "init";
|
|
6636
|
-
}
|
|
6637
|
-
// 返回最终结果
|
|
6638
|
-
const models = Object.keys(schemas);
|
|
6639
|
-
const successModels = statusResult?.Data?.SuccessResourceIdList || [];
|
|
6640
|
-
const failedModels = models.filter((model) => !successModels.includes(model));
|
|
6502
|
+
const cloudbase = await getManager();
|
|
6503
|
+
let currentEnvId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
6504
|
+
const schemas = mermaidToJsonSchema(mermaidDiagram);
|
|
6505
|
+
if (!schemas || Object.keys(schemas).length === 0) {
|
|
6641
6506
|
return {
|
|
6642
6507
|
content: [
|
|
6643
6508
|
{
|
|
6644
6509
|
type: "text",
|
|
6645
6510
|
text: JSON.stringify({
|
|
6646
|
-
success:
|
|
6647
|
-
|
|
6648
|
-
|
|
6649
|
-
models: models,
|
|
6650
|
-
successModels: successModels,
|
|
6651
|
-
failedModels: failedModels,
|
|
6652
|
-
status: status,
|
|
6653
|
-
action: action,
|
|
6654
|
-
message: status === "success"
|
|
6655
|
-
? `数据模型${action === "create" ? "创建" : "更新"}成功,共处理${models.length}个模型`
|
|
6656
|
-
: status === "init"
|
|
6657
|
-
? `任务超时,任务ID: ${taskId},请稍后手动查询状态`
|
|
6658
|
-
: `数据模型${action === "create" ? "创建" : "更新"}失败`,
|
|
6659
|
-
taskResult: statusResult?.Data,
|
|
6511
|
+
success: false,
|
|
6512
|
+
error: "No schemas generated from Mermaid diagram",
|
|
6513
|
+
message: "无法从Mermaid图表生成数据模型Schema",
|
|
6660
6514
|
}, null, 2),
|
|
6661
6515
|
},
|
|
6662
6516
|
],
|
|
6663
6517
|
};
|
|
6664
6518
|
}
|
|
6665
|
-
|
|
6519
|
+
// 创建数据模型列表
|
|
6520
|
+
const createDataModelList = Object.entries(schemas).map(([name, schema]) => {
|
|
6521
|
+
return {
|
|
6522
|
+
CreateSource: "cloudbase_create",
|
|
6523
|
+
Creator: null,
|
|
6524
|
+
DbLinkName: null,
|
|
6525
|
+
Description: schema.description ||
|
|
6526
|
+
`${schema.title || name}数据模型`,
|
|
6527
|
+
Schema: JSON.stringify(createBackendSchemaParams(schema)),
|
|
6528
|
+
Title: schema.title || name,
|
|
6529
|
+
Name: name,
|
|
6530
|
+
TableNameRule: "only_name",
|
|
6531
|
+
};
|
|
6532
|
+
});
|
|
6533
|
+
// 调用批量创建数据模型API
|
|
6534
|
+
const result = await cloudbase.commonService("lowcode").call({
|
|
6535
|
+
Action: "BatchCreateDataModelList",
|
|
6536
|
+
Param: {
|
|
6537
|
+
CreateDataModelList: createDataModelList,
|
|
6538
|
+
Creator: null,
|
|
6539
|
+
DbInstanceType: dbInstanceType,
|
|
6540
|
+
EnvId: currentEnvId,
|
|
6541
|
+
},
|
|
6542
|
+
});
|
|
6543
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
6544
|
+
const taskId = result.Data?.TaskId;
|
|
6545
|
+
if (!taskId) {
|
|
6666
6546
|
return {
|
|
6667
6547
|
content: [
|
|
6668
6548
|
{
|
|
6669
6549
|
type: "text",
|
|
6670
6550
|
text: JSON.stringify({
|
|
6671
6551
|
success: false,
|
|
6672
|
-
|
|
6673
|
-
|
|
6674
|
-
message: "
|
|
6552
|
+
requestId: result.RequestId,
|
|
6553
|
+
error: "No TaskId returned",
|
|
6554
|
+
message: "创建任务失败,未返回任务ID",
|
|
6675
6555
|
}, null, 2),
|
|
6676
6556
|
},
|
|
6677
6557
|
],
|
|
6678
6558
|
};
|
|
6679
6559
|
}
|
|
6560
|
+
// 轮询任务状态直至完成或超时
|
|
6561
|
+
const maxWaitTime = 30000; // 30秒超时
|
|
6562
|
+
const startTime = Date.now();
|
|
6563
|
+
let status = "init";
|
|
6564
|
+
let statusResult = null;
|
|
6565
|
+
while (status === "init" && Date.now() - startTime < maxWaitTime) {
|
|
6566
|
+
await new Promise((resolve) => setTimeout(resolve, 2000)); // 等待2秒
|
|
6567
|
+
statusResult = await cloudbase.commonService("lowcode").call({
|
|
6568
|
+
Action: "QueryModelTaskStatus",
|
|
6569
|
+
Param: {
|
|
6570
|
+
EnvId: currentEnvId,
|
|
6571
|
+
TaskId: taskId,
|
|
6572
|
+
},
|
|
6573
|
+
});
|
|
6574
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, statusResult);
|
|
6575
|
+
status = statusResult.Data?.Status || "init";
|
|
6576
|
+
}
|
|
6577
|
+
// 返回最终结果
|
|
6578
|
+
const models = Object.keys(schemas);
|
|
6579
|
+
const successModels = statusResult?.Data?.SuccessResourceIdList || [];
|
|
6580
|
+
const failedModels = models.filter((model) => !successModels.includes(model));
|
|
6581
|
+
return {
|
|
6582
|
+
content: [
|
|
6583
|
+
{
|
|
6584
|
+
type: "text",
|
|
6585
|
+
text: JSON.stringify({
|
|
6586
|
+
success: status === "success",
|
|
6587
|
+
requestId: result.RequestId,
|
|
6588
|
+
taskId: taskId,
|
|
6589
|
+
models: models,
|
|
6590
|
+
successModels: successModels,
|
|
6591
|
+
failedModels: failedModels,
|
|
6592
|
+
status: status,
|
|
6593
|
+
action: action,
|
|
6594
|
+
message: status === "success"
|
|
6595
|
+
? `数据模型${action === "create" ? "创建" : "更新"}成功,共处理${models.length}个模型`
|
|
6596
|
+
: status === "init"
|
|
6597
|
+
? `任务超时,任务ID: ${taskId},请稍后手动查询状态`
|
|
6598
|
+
: `数据模型${action === "create" ? "创建" : "更新"}失败`,
|
|
6599
|
+
taskResult: statusResult?.Data,
|
|
6600
|
+
}, null, 2),
|
|
6601
|
+
},
|
|
6602
|
+
],
|
|
6603
|
+
};
|
|
6680
6604
|
});
|
|
6681
6605
|
}
|
|
6682
6606
|
|
|
@@ -7491,41 +7415,25 @@ function registerInviteCodeTools(server) {
|
|
|
7491
7415
|
]
|
|
7492
7416
|
};
|
|
7493
7417
|
}
|
|
7494
|
-
|
|
7495
|
-
|
|
7496
|
-
|
|
7497
|
-
|
|
7498
|
-
|
|
7499
|
-
|
|
7500
|
-
|
|
7501
|
-
|
|
7502
|
-
|
|
7503
|
-
|
|
7504
|
-
|
|
7505
|
-
|
|
7506
|
-
|
|
7507
|
-
|
|
7508
|
-
|
|
7509
|
-
|
|
7510
|
-
|
|
7511
|
-
|
|
7512
|
-
|
|
7513
|
-
};
|
|
7514
|
-
}
|
|
7515
|
-
catch (e) {
|
|
7516
|
-
return {
|
|
7517
|
-
content: [
|
|
7518
|
-
{
|
|
7519
|
-
type: "text",
|
|
7520
|
-
text: JSON.stringify({
|
|
7521
|
-
ErrorCode: e.code || 'Exception',
|
|
7522
|
-
ErrorMsg: '激活失败:' + e.message,
|
|
7523
|
-
RequestId: e.RequestId || ''
|
|
7524
|
-
}, null, 2)
|
|
7525
|
-
}
|
|
7526
|
-
]
|
|
7527
|
-
};
|
|
7528
|
-
}
|
|
7418
|
+
const manager = await getManager();
|
|
7419
|
+
const EnvId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
7420
|
+
const result = await manager.commonService().call({
|
|
7421
|
+
Action: 'ActivateInviteCode',
|
|
7422
|
+
Param: { InviteCode, EnvId }
|
|
7423
|
+
});
|
|
7424
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
7425
|
+
return {
|
|
7426
|
+
content: [
|
|
7427
|
+
{
|
|
7428
|
+
type: "text",
|
|
7429
|
+
text: JSON.stringify({
|
|
7430
|
+
ErrorCode: result?.ErrorCode || '',
|
|
7431
|
+
ErrorMsg: result?.ErrorMsg || '',
|
|
7432
|
+
RequestId: result?.RequestId || ''
|
|
7433
|
+
}, null, 2)
|
|
7434
|
+
}
|
|
7435
|
+
]
|
|
7436
|
+
};
|
|
7529
7437
|
});
|
|
7530
7438
|
}
|
|
7531
7439
|
|
|
@@ -7570,94 +7478,78 @@ function registerStorageTools(server) {
|
|
|
7570
7478
|
category: "storage"
|
|
7571
7479
|
}
|
|
7572
7480
|
}, async (args) => {
|
|
7573
|
-
|
|
7574
|
-
|
|
7575
|
-
|
|
7576
|
-
|
|
7577
|
-
|
|
7578
|
-
|
|
7579
|
-
|
|
7580
|
-
|
|
7581
|
-
|
|
7582
|
-
|
|
7583
|
-
|
|
7584
|
-
|
|
7585
|
-
|
|
7586
|
-
|
|
7587
|
-
|
|
7588
|
-
|
|
7589
|
-
|
|
7590
|
-
|
|
7591
|
-
|
|
7592
|
-
|
|
7593
|
-
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
|
|
7598
|
-
|
|
7599
|
-
|
|
7600
|
-
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
|
|
7604
|
-
|
|
7605
|
-
|
|
7606
|
-
|
|
7607
|
-
|
|
7608
|
-
|
|
7609
|
-
|
|
7610
|
-
|
|
7611
|
-
|
|
7612
|
-
|
|
7613
|
-
|
|
7614
|
-
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
|
|
7627
|
-
|
|
7628
|
-
|
|
7629
|
-
|
|
7630
|
-
|
|
7631
|
-
|
|
7632
|
-
|
|
7633
|
-
|
|
7634
|
-
|
|
7635
|
-
|
|
7636
|
-
|
|
7637
|
-
|
|
7638
|
-
|
|
7639
|
-
|
|
7640
|
-
|
|
7641
|
-
|
|
7642
|
-
};
|
|
7643
|
-
}
|
|
7644
|
-
default:
|
|
7645
|
-
throw new Error(`Unsupported action: ${input.action}`);
|
|
7481
|
+
const input = args;
|
|
7482
|
+
const manager = await getManager();
|
|
7483
|
+
if (!manager) {
|
|
7484
|
+
throw new Error("Failed to initialize CloudBase manager. Please check your credentials and environment configuration.");
|
|
7485
|
+
}
|
|
7486
|
+
const storageService = manager.storage;
|
|
7487
|
+
switch (input.action) {
|
|
7488
|
+
case 'list': {
|
|
7489
|
+
const result = await storageService.listDirectoryFiles(input.cloudPath);
|
|
7490
|
+
return {
|
|
7491
|
+
content: [
|
|
7492
|
+
{
|
|
7493
|
+
type: "text",
|
|
7494
|
+
text: JSON.stringify({
|
|
7495
|
+
success: true,
|
|
7496
|
+
data: {
|
|
7497
|
+
action: 'list',
|
|
7498
|
+
cloudPath: input.cloudPath,
|
|
7499
|
+
files: result || [],
|
|
7500
|
+
totalCount: result?.length || 0
|
|
7501
|
+
},
|
|
7502
|
+
message: `Successfully listed ${result?.length || 0} files in directory '${input.cloudPath}'`
|
|
7503
|
+
}, null, 2)
|
|
7504
|
+
}
|
|
7505
|
+
]
|
|
7506
|
+
};
|
|
7507
|
+
}
|
|
7508
|
+
case 'info': {
|
|
7509
|
+
const result = await storageService.getFileInfo(input.cloudPath);
|
|
7510
|
+
return {
|
|
7511
|
+
content: [
|
|
7512
|
+
{
|
|
7513
|
+
type: "text",
|
|
7514
|
+
text: JSON.stringify({
|
|
7515
|
+
success: true,
|
|
7516
|
+
data: {
|
|
7517
|
+
action: 'info',
|
|
7518
|
+
cloudPath: input.cloudPath,
|
|
7519
|
+
fileInfo: result
|
|
7520
|
+
},
|
|
7521
|
+
message: `Successfully retrieved file info for '${input.cloudPath}'`
|
|
7522
|
+
}, null, 2)
|
|
7523
|
+
}
|
|
7524
|
+
]
|
|
7525
|
+
};
|
|
7526
|
+
}
|
|
7527
|
+
case 'url': {
|
|
7528
|
+
const result = await storageService.getTemporaryUrl([{
|
|
7529
|
+
cloudPath: input.cloudPath,
|
|
7530
|
+
maxAge: input.maxAge || 3600
|
|
7531
|
+
}]);
|
|
7532
|
+
return {
|
|
7533
|
+
content: [
|
|
7534
|
+
{
|
|
7535
|
+
type: "text",
|
|
7536
|
+
text: JSON.stringify({
|
|
7537
|
+
success: true,
|
|
7538
|
+
data: {
|
|
7539
|
+
action: 'url',
|
|
7540
|
+
cloudPath: input.cloudPath,
|
|
7541
|
+
temporaryUrl: result[0]?.url || "",
|
|
7542
|
+
expireTime: `${input.maxAge || 3600}秒`,
|
|
7543
|
+
fileId: result[0]?.fileId || ""
|
|
7544
|
+
},
|
|
7545
|
+
message: `Successfully generated temporary URL for '${input.cloudPath}'`
|
|
7546
|
+
}, null, 2)
|
|
7547
|
+
}
|
|
7548
|
+
]
|
|
7549
|
+
};
|
|
7646
7550
|
}
|
|
7647
|
-
|
|
7648
|
-
|
|
7649
|
-
return {
|
|
7650
|
-
content: [
|
|
7651
|
-
{
|
|
7652
|
-
type: "text",
|
|
7653
|
-
text: JSON.stringify({
|
|
7654
|
-
success: false,
|
|
7655
|
-
error: error.message || 'Unknown error occurred',
|
|
7656
|
-
message: `Failed to query storage information. Please check your permissions and parameters.`
|
|
7657
|
-
}, null, 2)
|
|
7658
|
-
}
|
|
7659
|
-
]
|
|
7660
|
-
};
|
|
7551
|
+
default:
|
|
7552
|
+
throw new Error(`Unsupported action: ${input.action}`);
|
|
7661
7553
|
}
|
|
7662
7554
|
});
|
|
7663
7555
|
// Tool 2: manageStorage - 管理存储文件(写操作)
|
|
@@ -7673,151 +7565,128 @@ function registerStorageTools(server) {
|
|
|
7673
7565
|
category: "storage"
|
|
7674
7566
|
}
|
|
7675
7567
|
}, async (args) => {
|
|
7676
|
-
|
|
7677
|
-
|
|
7678
|
-
|
|
7679
|
-
|
|
7680
|
-
|
|
7681
|
-
|
|
7682
|
-
|
|
7683
|
-
|
|
7684
|
-
|
|
7685
|
-
|
|
7686
|
-
|
|
7687
|
-
|
|
7688
|
-
|
|
7689
|
-
|
|
7690
|
-
|
|
7691
|
-
|
|
7692
|
-
}
|
|
7693
|
-
});
|
|
7694
|
-
}
|
|
7695
|
-
else {
|
|
7696
|
-
// 上传文件
|
|
7697
|
-
await storageService.uploadFile({
|
|
7698
|
-
localPath: input.localPath,
|
|
7699
|
-
cloudPath: input.cloudPath,
|
|
7700
|
-
onProgress: (progressData) => {
|
|
7701
|
-
console.log("Upload file progress:", progressData);
|
|
7702
|
-
}
|
|
7703
|
-
});
|
|
7704
|
-
}
|
|
7705
|
-
// 获取文件临时下载地址
|
|
7706
|
-
const fileUrls = await storageService.getTemporaryUrl([{
|
|
7707
|
-
cloudPath: input.cloudPath,
|
|
7708
|
-
maxAge: 3600 // 临时链接有效期1小时
|
|
7709
|
-
}]);
|
|
7710
|
-
return {
|
|
7711
|
-
content: [
|
|
7712
|
-
{
|
|
7713
|
-
type: "text",
|
|
7714
|
-
text: JSON.stringify({
|
|
7715
|
-
success: true,
|
|
7716
|
-
data: {
|
|
7717
|
-
action: 'upload',
|
|
7718
|
-
localPath: input.localPath,
|
|
7719
|
-
cloudPath: input.cloudPath,
|
|
7720
|
-
isDirectory: input.isDirectory,
|
|
7721
|
-
temporaryUrl: fileUrls[0]?.url || "",
|
|
7722
|
-
expireTime: "1小时"
|
|
7723
|
-
},
|
|
7724
|
-
message: `Successfully uploaded ${input.isDirectory ? 'directory' : 'file'} from '${input.localPath}' to '${input.cloudPath}'`
|
|
7725
|
-
}, null, 2)
|
|
7726
|
-
}
|
|
7727
|
-
]
|
|
7728
|
-
};
|
|
7568
|
+
const input = args;
|
|
7569
|
+
const manager = await getManager();
|
|
7570
|
+
if (!manager) {
|
|
7571
|
+
throw new Error("Failed to initialize CloudBase manager. Please check your credentials and environment configuration.");
|
|
7572
|
+
}
|
|
7573
|
+
const storageService = manager.storage;
|
|
7574
|
+
switch (input.action) {
|
|
7575
|
+
case 'upload': {
|
|
7576
|
+
if (input.isDirectory) {
|
|
7577
|
+
await storageService.uploadDirectory({
|
|
7578
|
+
localPath: input.localPath,
|
|
7579
|
+
cloudPath: input.cloudPath,
|
|
7580
|
+
onProgress: (progressData) => {
|
|
7581
|
+
console.log("Upload directory progress:", progressData);
|
|
7582
|
+
}
|
|
7583
|
+
});
|
|
7729
7584
|
}
|
|
7730
|
-
|
|
7731
|
-
|
|
7732
|
-
|
|
7733
|
-
|
|
7734
|
-
|
|
7735
|
-
|
|
7736
|
-
}
|
|
7737
|
-
}
|
|
7738
|
-
else {
|
|
7739
|
-
// 下载文件
|
|
7740
|
-
await storageService.downloadFile({
|
|
7741
|
-
cloudPath: input.cloudPath,
|
|
7742
|
-
localPath: input.localPath
|
|
7743
|
-
});
|
|
7744
|
-
}
|
|
7745
|
-
return {
|
|
7746
|
-
content: [
|
|
7747
|
-
{
|
|
7748
|
-
type: "text",
|
|
7749
|
-
text: JSON.stringify({
|
|
7750
|
-
success: true,
|
|
7751
|
-
data: {
|
|
7752
|
-
action: 'download',
|
|
7753
|
-
cloudPath: input.cloudPath,
|
|
7754
|
-
localPath: input.localPath,
|
|
7755
|
-
isDirectory: input.isDirectory
|
|
7756
|
-
},
|
|
7757
|
-
message: `Successfully downloaded ${input.isDirectory ? 'directory' : 'file'} from '${input.cloudPath}' to '${input.localPath}'`
|
|
7758
|
-
}, null, 2)
|
|
7759
|
-
}
|
|
7760
|
-
]
|
|
7761
|
-
};
|
|
7585
|
+
else {
|
|
7586
|
+
await storageService.uploadFile({
|
|
7587
|
+
localPath: input.localPath,
|
|
7588
|
+
cloudPath: input.cloudPath,
|
|
7589
|
+
onProgress: (progressData) => {
|
|
7590
|
+
console.log("Upload file progress:", progressData);
|
|
7591
|
+
}
|
|
7592
|
+
});
|
|
7762
7593
|
}
|
|
7763
|
-
|
|
7764
|
-
|
|
7765
|
-
|
|
7766
|
-
|
|
7767
|
-
|
|
7768
|
-
|
|
7769
|
-
|
|
7770
|
-
|
|
7771
|
-
|
|
7772
|
-
|
|
7773
|
-
|
|
7774
|
-
|
|
7775
|
-
|
|
7776
|
-
|
|
7777
|
-
|
|
7778
|
-
|
|
7779
|
-
|
|
7780
|
-
|
|
7781
|
-
|
|
7782
|
-
|
|
7783
|
-
|
|
7784
|
-
|
|
7785
|
-
|
|
7594
|
+
const fileUrls = await storageService.getTemporaryUrl([{
|
|
7595
|
+
cloudPath: input.cloudPath,
|
|
7596
|
+
maxAge: 3600
|
|
7597
|
+
}]);
|
|
7598
|
+
return {
|
|
7599
|
+
content: [
|
|
7600
|
+
{
|
|
7601
|
+
type: "text",
|
|
7602
|
+
text: JSON.stringify({
|
|
7603
|
+
success: true,
|
|
7604
|
+
data: {
|
|
7605
|
+
action: 'upload',
|
|
7606
|
+
localPath: input.localPath,
|
|
7607
|
+
cloudPath: input.cloudPath,
|
|
7608
|
+
isDirectory: input.isDirectory,
|
|
7609
|
+
temporaryUrl: fileUrls[0]?.url || "",
|
|
7610
|
+
expireTime: "1小时"
|
|
7611
|
+
},
|
|
7612
|
+
message: `Successfully uploaded ${input.isDirectory ? 'directory' : 'file'} from '${input.localPath}' to '${input.cloudPath}'`
|
|
7613
|
+
}, null, 2)
|
|
7614
|
+
}
|
|
7615
|
+
]
|
|
7616
|
+
};
|
|
7617
|
+
}
|
|
7618
|
+
case 'download': {
|
|
7619
|
+
if (input.isDirectory) {
|
|
7620
|
+
await storageService.downloadDirectory({
|
|
7621
|
+
cloudPath: input.cloudPath,
|
|
7622
|
+
localPath: input.localPath
|
|
7623
|
+
});
|
|
7624
|
+
}
|
|
7625
|
+
else {
|
|
7626
|
+
await storageService.downloadFile({
|
|
7627
|
+
cloudPath: input.cloudPath,
|
|
7628
|
+
localPath: input.localPath
|
|
7629
|
+
});
|
|
7630
|
+
}
|
|
7631
|
+
return {
|
|
7632
|
+
content: [
|
|
7633
|
+
{
|
|
7634
|
+
type: "text",
|
|
7635
|
+
text: JSON.stringify({
|
|
7636
|
+
success: true,
|
|
7637
|
+
data: {
|
|
7638
|
+
action: 'download',
|
|
7639
|
+
cloudPath: input.cloudPath,
|
|
7640
|
+
localPath: input.localPath,
|
|
7641
|
+
isDirectory: input.isDirectory
|
|
7642
|
+
},
|
|
7643
|
+
message: `Successfully downloaded ${input.isDirectory ? 'directory' : 'file'} from '${input.cloudPath}' to '${input.localPath}'`
|
|
7644
|
+
}, null, 2)
|
|
7645
|
+
}
|
|
7646
|
+
]
|
|
7647
|
+
};
|
|
7648
|
+
}
|
|
7649
|
+
case 'delete': {
|
|
7650
|
+
if (!input.force) {
|
|
7786
7651
|
return {
|
|
7787
7652
|
content: [
|
|
7788
7653
|
{
|
|
7789
7654
|
type: "text",
|
|
7790
7655
|
text: JSON.stringify({
|
|
7791
|
-
success:
|
|
7792
|
-
|
|
7793
|
-
|
|
7794
|
-
cloudPath: input.cloudPath,
|
|
7795
|
-
isDirectory: input.isDirectory,
|
|
7796
|
-
deleted: true
|
|
7797
|
-
},
|
|
7798
|
-
message: `Successfully deleted ${input.isDirectory ? 'directory' : 'file'} '${input.cloudPath}'`
|
|
7656
|
+
success: false,
|
|
7657
|
+
error: "Delete operation requires confirmation",
|
|
7658
|
+
message: "Please set force: true to confirm deletion. This action cannot be undone."
|
|
7799
7659
|
}, null, 2)
|
|
7800
7660
|
}
|
|
7801
7661
|
]
|
|
7802
7662
|
};
|
|
7803
7663
|
}
|
|
7804
|
-
|
|
7805
|
-
|
|
7664
|
+
if (input.isDirectory) {
|
|
7665
|
+
await storageService.deleteDirectory(input.cloudPath);
|
|
7666
|
+
}
|
|
7667
|
+
else {
|
|
7668
|
+
await storageService.deleteFile([input.cloudPath]);
|
|
7669
|
+
}
|
|
7670
|
+
return {
|
|
7671
|
+
content: [
|
|
7672
|
+
{
|
|
7673
|
+
type: "text",
|
|
7674
|
+
text: JSON.stringify({
|
|
7675
|
+
success: true,
|
|
7676
|
+
data: {
|
|
7677
|
+
action: 'delete',
|
|
7678
|
+
cloudPath: input.cloudPath,
|
|
7679
|
+
isDirectory: input.isDirectory,
|
|
7680
|
+
deleted: true
|
|
7681
|
+
},
|
|
7682
|
+
message: `Successfully deleted ${input.isDirectory ? 'directory' : 'file'} '${input.cloudPath}'`
|
|
7683
|
+
}, null, 2)
|
|
7684
|
+
}
|
|
7685
|
+
]
|
|
7686
|
+
};
|
|
7806
7687
|
}
|
|
7807
|
-
|
|
7808
|
-
|
|
7809
|
-
return {
|
|
7810
|
-
content: [
|
|
7811
|
-
{
|
|
7812
|
-
type: "text",
|
|
7813
|
-
text: JSON.stringify({
|
|
7814
|
-
success: false,
|
|
7815
|
-
error: error.message || 'Unknown error occurred',
|
|
7816
|
-
message: `Failed to manage storage. Please check your permissions and parameters.`
|
|
7817
|
-
}, null, 2)
|
|
7818
|
-
}
|
|
7819
|
-
]
|
|
7820
|
-
};
|
|
7688
|
+
default:
|
|
7689
|
+
throw new Error(`Unsupported action: ${input.action}`);
|
|
7821
7690
|
}
|
|
7822
7691
|
});
|
|
7823
7692
|
}
|
|
@@ -7991,113 +7860,97 @@ function registerCloudRunTools(server) {
|
|
|
7991
7860
|
category: "cloudrun"
|
|
7992
7861
|
}
|
|
7993
7862
|
}, async (args) => {
|
|
7994
|
-
|
|
7995
|
-
|
|
7996
|
-
|
|
7997
|
-
|
|
7998
|
-
|
|
7999
|
-
|
|
8000
|
-
|
|
8001
|
-
|
|
8002
|
-
|
|
8003
|
-
|
|
8004
|
-
|
|
8005
|
-
|
|
8006
|
-
|
|
8007
|
-
|
|
8008
|
-
listParams.serverName = input.serverName;
|
|
8009
|
-
}
|
|
8010
|
-
if (input.serverType) {
|
|
8011
|
-
listParams.serverType = input.serverType;
|
|
8012
|
-
}
|
|
8013
|
-
const result = await cloudrunService.list(listParams);
|
|
8014
|
-
return {
|
|
8015
|
-
content: [
|
|
8016
|
-
{
|
|
8017
|
-
type: "text",
|
|
8018
|
-
text: JSON.stringify({
|
|
8019
|
-
success: true,
|
|
8020
|
-
data: {
|
|
8021
|
-
services: result.ServerList || [],
|
|
8022
|
-
pagination: {
|
|
8023
|
-
total: result.Total || 0,
|
|
8024
|
-
pageSize: input.pageSize,
|
|
8025
|
-
pageNum: input.pageNum,
|
|
8026
|
-
totalPages: Math.ceil((result.Total || 0) / (input.pageSize || 10))
|
|
8027
|
-
}
|
|
8028
|
-
},
|
|
8029
|
-
message: `Found ${result.ServerList?.length || 0} CloudRun services`
|
|
8030
|
-
}, null, 2)
|
|
8031
|
-
}
|
|
8032
|
-
]
|
|
8033
|
-
};
|
|
7863
|
+
const input = args;
|
|
7864
|
+
const manager = await getManager();
|
|
7865
|
+
if (!manager) {
|
|
7866
|
+
throw new Error("Failed to initialize CloudBase manager. Please check your credentials and environment configuration.");
|
|
7867
|
+
}
|
|
7868
|
+
const cloudrunService = manager.cloudrun;
|
|
7869
|
+
switch (input.action) {
|
|
7870
|
+
case 'list': {
|
|
7871
|
+
const listParams = {
|
|
7872
|
+
pageSize: input.pageSize,
|
|
7873
|
+
pageNum: input.pageNum,
|
|
7874
|
+
};
|
|
7875
|
+
if (input.serverName) {
|
|
7876
|
+
listParams.serverName = input.serverName;
|
|
8034
7877
|
}
|
|
8035
|
-
|
|
8036
|
-
|
|
8037
|
-
const result = await cloudrunService.detail({ serverName });
|
|
8038
|
-
if (!result) {
|
|
8039
|
-
return {
|
|
8040
|
-
content: [
|
|
8041
|
-
{
|
|
8042
|
-
type: "text",
|
|
8043
|
-
text: JSON.stringify({
|
|
8044
|
-
success: false,
|
|
8045
|
-
error: `Service '${serverName}' not found`,
|
|
8046
|
-
message: "Please check the service name and try again."
|
|
8047
|
-
}, null, 2)
|
|
8048
|
-
}
|
|
8049
|
-
]
|
|
8050
|
-
};
|
|
8051
|
-
}
|
|
8052
|
-
return {
|
|
8053
|
-
content: [
|
|
8054
|
-
{
|
|
8055
|
-
type: "text",
|
|
8056
|
-
text: JSON.stringify({
|
|
8057
|
-
success: true,
|
|
8058
|
-
data: {
|
|
8059
|
-
service: result
|
|
8060
|
-
},
|
|
8061
|
-
message: `Retrieved details for service '${serverName}'`
|
|
8062
|
-
}, null, 2)
|
|
8063
|
-
}
|
|
8064
|
-
]
|
|
8065
|
-
};
|
|
7878
|
+
if (input.serverType) {
|
|
7879
|
+
listParams.serverType = input.serverType;
|
|
8066
7880
|
}
|
|
8067
|
-
|
|
8068
|
-
|
|
7881
|
+
const result = await cloudrunService.list(listParams);
|
|
7882
|
+
return {
|
|
7883
|
+
content: [
|
|
7884
|
+
{
|
|
7885
|
+
type: "text",
|
|
7886
|
+
text: JSON.stringify({
|
|
7887
|
+
success: true,
|
|
7888
|
+
data: {
|
|
7889
|
+
services: result.ServerList || [],
|
|
7890
|
+
pagination: {
|
|
7891
|
+
total: result.Total || 0,
|
|
7892
|
+
pageSize: input.pageSize,
|
|
7893
|
+
pageNum: input.pageNum,
|
|
7894
|
+
totalPages: Math.ceil((result.Total || 0) / (input.pageSize || 10))
|
|
7895
|
+
}
|
|
7896
|
+
},
|
|
7897
|
+
message: `Found ${result.ServerList?.length || 0} CloudRun services`
|
|
7898
|
+
}, null, 2)
|
|
7899
|
+
}
|
|
7900
|
+
]
|
|
7901
|
+
};
|
|
7902
|
+
}
|
|
7903
|
+
case 'detail': {
|
|
7904
|
+
const serverName = input.detailServerName || input.serverName;
|
|
7905
|
+
const result = await cloudrunService.detail({ serverName });
|
|
7906
|
+
if (!result) {
|
|
8069
7907
|
return {
|
|
8070
7908
|
content: [
|
|
8071
7909
|
{
|
|
8072
7910
|
type: "text",
|
|
8073
7911
|
text: JSON.stringify({
|
|
8074
|
-
success:
|
|
8075
|
-
|
|
8076
|
-
|
|
8077
|
-
},
|
|
8078
|
-
message: `Found ${result?.length || 0} available templates`
|
|
7912
|
+
success: false,
|
|
7913
|
+
error: `Service '${serverName}' not found`,
|
|
7914
|
+
message: "Please check the service name and try again."
|
|
8079
7915
|
}, null, 2)
|
|
8080
7916
|
}
|
|
8081
7917
|
]
|
|
8082
7918
|
};
|
|
8083
7919
|
}
|
|
8084
|
-
|
|
8085
|
-
|
|
7920
|
+
return {
|
|
7921
|
+
content: [
|
|
7922
|
+
{
|
|
7923
|
+
type: "text",
|
|
7924
|
+
text: JSON.stringify({
|
|
7925
|
+
success: true,
|
|
7926
|
+
data: {
|
|
7927
|
+
service: result
|
|
7928
|
+
},
|
|
7929
|
+
message: `Retrieved details for service '${serverName}'`
|
|
7930
|
+
}, null, 2)
|
|
7931
|
+
}
|
|
7932
|
+
]
|
|
7933
|
+
};
|
|
8086
7934
|
}
|
|
8087
|
-
|
|
8088
|
-
|
|
8089
|
-
|
|
8090
|
-
|
|
8091
|
-
|
|
8092
|
-
|
|
8093
|
-
|
|
8094
|
-
|
|
8095
|
-
|
|
8096
|
-
|
|
8097
|
-
|
|
8098
|
-
|
|
8099
|
-
|
|
8100
|
-
|
|
7935
|
+
case 'templates': {
|
|
7936
|
+
const result = await cloudrunService.getTemplates();
|
|
7937
|
+
return {
|
|
7938
|
+
content: [
|
|
7939
|
+
{
|
|
7940
|
+
type: "text",
|
|
7941
|
+
text: JSON.stringify({
|
|
7942
|
+
success: true,
|
|
7943
|
+
data: {
|
|
7944
|
+
templates: result || []
|
|
7945
|
+
},
|
|
7946
|
+
message: `Found ${result?.length || 0} available templates`
|
|
7947
|
+
}, null, 2)
|
|
7948
|
+
}
|
|
7949
|
+
]
|
|
7950
|
+
};
|
|
7951
|
+
}
|
|
7952
|
+
default:
|
|
7953
|
+
throw new Error(`Unsupported action: ${input.action}`);
|
|
8101
7954
|
}
|
|
8102
7955
|
});
|
|
8103
7956
|
// Track local running processes for CloudRun function services
|
|
@@ -8115,62 +7968,60 @@ function registerCloudRunTools(server) {
|
|
|
8115
7968
|
category: "cloudrun"
|
|
8116
7969
|
}
|
|
8117
7970
|
}, async (args) => {
|
|
8118
|
-
|
|
8119
|
-
|
|
8120
|
-
|
|
8121
|
-
|
|
8122
|
-
|
|
8123
|
-
|
|
8124
|
-
|
|
8125
|
-
|
|
8126
|
-
|
|
8127
|
-
|
|
8128
|
-
|
|
8129
|
-
|
|
8130
|
-
|
|
8131
|
-
|
|
8132
|
-
|
|
8133
|
-
|
|
8134
|
-
|
|
8135
|
-
|
|
8136
|
-
|
|
8137
|
-
|
|
8138
|
-
|
|
8139
|
-
|
|
8140
|
-
|
|
8141
|
-
|
|
8142
|
-
|
|
8143
|
-
|
|
8144
|
-
|
|
8145
|
-
|
|
8146
|
-
|
|
8147
|
-
|
|
8148
|
-
|
|
8149
|
-
|
|
8150
|
-
|
|
8151
|
-
|
|
7971
|
+
const input = args;
|
|
7972
|
+
const manager = await getManager();
|
|
7973
|
+
if (!manager) {
|
|
7974
|
+
throw new Error("Failed to initialize CloudBase manager. Please check your credentials and environment configuration.");
|
|
7975
|
+
}
|
|
7976
|
+
const cloudrunService = manager.cloudrun;
|
|
7977
|
+
let targetPath;
|
|
7978
|
+
if (input.targetPath) {
|
|
7979
|
+
targetPath = validateAndNormalizePath(input.targetPath);
|
|
7980
|
+
}
|
|
7981
|
+
switch (input.action) {
|
|
7982
|
+
case 'createAgent': {
|
|
7983
|
+
if (!targetPath) {
|
|
7984
|
+
throw new Error("targetPath is required for createAgent operation");
|
|
7985
|
+
}
|
|
7986
|
+
if (!input.agentConfig) {
|
|
7987
|
+
throw new Error("agentConfig is required for createAgent operation");
|
|
7988
|
+
}
|
|
7989
|
+
const { agentName, botTag, description, template = 'blank' } = input.agentConfig;
|
|
7990
|
+
// Generate BotId
|
|
7991
|
+
const botId = botTag ? `ibot-${agentName}-${botTag}` : `ibot-${agentName}-${Date.now()}`;
|
|
7992
|
+
// Create Agent using CloudBase Manager
|
|
7993
|
+
const agentResult = await manager.agent.createFunctionAgent(targetPath, {
|
|
7994
|
+
Name: agentName,
|
|
7995
|
+
BotId: botId,
|
|
7996
|
+
Introduction: description || `Agent created by ${agentName}`,
|
|
7997
|
+
Avatar: undefined
|
|
7998
|
+
});
|
|
7999
|
+
// Create project directory
|
|
8000
|
+
const projectDir = path_1.default.join(targetPath, input.serverName);
|
|
8001
|
+
if (!fs_1.default.existsSync(projectDir)) {
|
|
8002
|
+
fs_1.default.mkdirSync(projectDir, { recursive: true });
|
|
8003
|
+
}
|
|
8004
|
+
// Generate package.json
|
|
8005
|
+
const packageJson = {
|
|
8006
|
+
name: input.serverName,
|
|
8007
|
+
version: "1.0.0",
|
|
8008
|
+
description: description || `Agent created by ${agentName}`,
|
|
8009
|
+
main: "index.js",
|
|
8010
|
+
scripts: {
|
|
8011
|
+
"dev": "tcb cloudrun run --runMode=agent -w",
|
|
8012
|
+
"deploy": "tcb cloudrun deploy",
|
|
8013
|
+
"start": "node index.js"
|
|
8014
|
+
},
|
|
8015
|
+
dependencies: {
|
|
8016
|
+
"@cloudbase/aiagent-framework": "^1.0.0-beta.10"
|
|
8017
|
+
},
|
|
8018
|
+
devDependencies: {
|
|
8019
|
+
"@cloudbase/cli": "^2.6.16"
|
|
8152
8020
|
}
|
|
8153
|
-
|
|
8154
|
-
|
|
8155
|
-
|
|
8156
|
-
|
|
8157
|
-
description: description || `Agent created by ${agentName}`,
|
|
8158
|
-
main: "index.js",
|
|
8159
|
-
scripts: {
|
|
8160
|
-
"dev": "tcb cloudrun run --runMode=agent -w",
|
|
8161
|
-
"deploy": "tcb cloudrun deploy",
|
|
8162
|
-
"start": "node index.js"
|
|
8163
|
-
},
|
|
8164
|
-
dependencies: {
|
|
8165
|
-
"@cloudbase/aiagent-framework": "^1.0.0-beta.10"
|
|
8166
|
-
},
|
|
8167
|
-
devDependencies: {
|
|
8168
|
-
"@cloudbase/cli": "^2.6.16"
|
|
8169
|
-
}
|
|
8170
|
-
};
|
|
8171
|
-
fs_1.default.writeFileSync(path_1.default.join(projectDir, 'package.json'), JSON.stringify(packageJson, null, 2));
|
|
8172
|
-
// Generate index.js with Agent template
|
|
8173
|
-
const indexJsContent = `const { IBot } = require("@cloudbase/aiagent-framework");
|
|
8021
|
+
};
|
|
8022
|
+
fs_1.default.writeFileSync(path_1.default.join(projectDir, 'package.json'), JSON.stringify(packageJson, null, 2));
|
|
8023
|
+
// Generate index.js with Agent template
|
|
8024
|
+
const indexJsContent = `const { IBot } = require("@cloudbase/aiagent-framework");
|
|
8174
8025
|
const { BotRunner } = require("@cloudbase/aiagent-framework");
|
|
8175
8026
|
|
|
8176
8027
|
const ANSWER = "你好,我是一个智能体,但我只会说这一句话。";
|
|
@@ -8215,18 +8066,18 @@ exports.main = function (event, context) {
|
|
|
8215
8066
|
return BotRunner.run(event, context, new MyBot(context));
|
|
8216
8067
|
};
|
|
8217
8068
|
`;
|
|
8218
|
-
|
|
8219
|
-
|
|
8220
|
-
|
|
8221
|
-
|
|
8222
|
-
|
|
8223
|
-
|
|
8224
|
-
|
|
8225
|
-
|
|
8226
|
-
|
|
8227
|
-
|
|
8228
|
-
|
|
8229
|
-
|
|
8069
|
+
fs_1.default.writeFileSync(path_1.default.join(projectDir, 'index.js'), indexJsContent);
|
|
8070
|
+
// Generate cloudbaserc.json
|
|
8071
|
+
const currentEnvId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
8072
|
+
const cloudbasercContent = {
|
|
8073
|
+
envId: currentEnvId,
|
|
8074
|
+
cloudrun: {
|
|
8075
|
+
name: input.serverName
|
|
8076
|
+
}
|
|
8077
|
+
};
|
|
8078
|
+
fs_1.default.writeFileSync(path_1.default.join(projectDir, 'cloudbaserc.json'), JSON.stringify(cloudbasercContent, null, 2));
|
|
8079
|
+
// Generate README.md
|
|
8080
|
+
const readmeContent = `# ${agentName} Agent
|
|
8230
8081
|
|
|
8231
8082
|
这是一个基于函数型云托管的 AI 智能体。
|
|
8232
8083
|
|
|
@@ -8271,230 +8122,230 @@ for await (let x of res.textStream) {
|
|
|
8271
8122
|
</script>
|
|
8272
8123
|
\`\`\`
|
|
8273
8124
|
`;
|
|
8274
|
-
|
|
8275
|
-
|
|
8276
|
-
|
|
8277
|
-
|
|
8278
|
-
|
|
8279
|
-
|
|
8280
|
-
|
|
8281
|
-
|
|
8282
|
-
|
|
8283
|
-
|
|
8284
|
-
|
|
8285
|
-
|
|
8286
|
-
|
|
8287
|
-
|
|
8288
|
-
|
|
8289
|
-
|
|
8290
|
-
|
|
8291
|
-
|
|
8292
|
-
|
|
8293
|
-
|
|
8125
|
+
fs_1.default.writeFileSync(path_1.default.join(projectDir, 'README.md'), readmeContent);
|
|
8126
|
+
return {
|
|
8127
|
+
content: [
|
|
8128
|
+
{
|
|
8129
|
+
type: "text",
|
|
8130
|
+
text: JSON.stringify({
|
|
8131
|
+
success: true,
|
|
8132
|
+
data: {
|
|
8133
|
+
agentName: agentName,
|
|
8134
|
+
botId: botId,
|
|
8135
|
+
projectDir: projectDir,
|
|
8136
|
+
serverName: input.serverName,
|
|
8137
|
+
template: template,
|
|
8138
|
+
filesCreated: ['package.json', 'index.js', 'cloudbaserc.json', 'README.md']
|
|
8139
|
+
},
|
|
8140
|
+
message: `Successfully created Agent '${agentName}' with BotId '${botId}' in ${projectDir}`
|
|
8141
|
+
}, null, 2)
|
|
8142
|
+
}
|
|
8143
|
+
]
|
|
8144
|
+
};
|
|
8145
|
+
}
|
|
8146
|
+
case 'deploy': {
|
|
8147
|
+
if (!targetPath) {
|
|
8148
|
+
throw new Error("targetPath is required for deploy operation");
|
|
8294
8149
|
}
|
|
8295
|
-
|
|
8296
|
-
|
|
8297
|
-
|
|
8298
|
-
|
|
8299
|
-
|
|
8300
|
-
|
|
8301
|
-
|
|
8302
|
-
|
|
8150
|
+
// Determine service type - use input.serverType if provided, otherwise auto-detect
|
|
8151
|
+
let serverType;
|
|
8152
|
+
if (input.serverType) {
|
|
8153
|
+
serverType = input.serverType;
|
|
8154
|
+
}
|
|
8155
|
+
else {
|
|
8156
|
+
try {
|
|
8157
|
+
// First try to get existing service details
|
|
8158
|
+
const details = await cloudrunService.detail({ serverName: input.serverName });
|
|
8159
|
+
serverType = details.BaseInfo?.ServerType || 'container';
|
|
8303
8160
|
}
|
|
8304
|
-
|
|
8305
|
-
|
|
8306
|
-
|
|
8307
|
-
|
|
8308
|
-
serverType =
|
|
8161
|
+
catch (e) {
|
|
8162
|
+
// If service doesn't exist, determine by project structure
|
|
8163
|
+
const dockerfilePath = path_1.default.join(targetPath, 'Dockerfile');
|
|
8164
|
+
if (fs_1.default.existsSync(dockerfilePath)) {
|
|
8165
|
+
serverType = 'container';
|
|
8309
8166
|
}
|
|
8310
|
-
|
|
8311
|
-
//
|
|
8312
|
-
const
|
|
8313
|
-
if (fs_1.default.existsSync(
|
|
8314
|
-
|
|
8315
|
-
|
|
8316
|
-
|
|
8317
|
-
|
|
8318
|
-
|
|
8319
|
-
|
|
8320
|
-
try {
|
|
8321
|
-
const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf8'));
|
|
8322
|
-
// If it has function-specific dependencies or scripts, treat as function
|
|
8323
|
-
if (packageJson.dependencies?.['@cloudbase/aiagent-framework'] ||
|
|
8324
|
-
packageJson.scripts?.['dev']?.includes('cloudrun run')) {
|
|
8325
|
-
serverType = 'function';
|
|
8326
|
-
}
|
|
8327
|
-
else {
|
|
8328
|
-
serverType = 'container';
|
|
8329
|
-
}
|
|
8167
|
+
else {
|
|
8168
|
+
// Check if it's a Node.js function project (has package.json with specific structure)
|
|
8169
|
+
const packageJsonPath = path_1.default.join(targetPath, 'package.json');
|
|
8170
|
+
if (fs_1.default.existsSync(packageJsonPath)) {
|
|
8171
|
+
try {
|
|
8172
|
+
const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf8'));
|
|
8173
|
+
// If it has function-specific dependencies or scripts, treat as function
|
|
8174
|
+
if (packageJson.dependencies?.['@cloudbase/aiagent-framework'] ||
|
|
8175
|
+
packageJson.scripts?.['dev']?.includes('cloudrun run')) {
|
|
8176
|
+
serverType = 'function';
|
|
8330
8177
|
}
|
|
8331
|
-
|
|
8178
|
+
else {
|
|
8332
8179
|
serverType = 'container';
|
|
8333
8180
|
}
|
|
8334
8181
|
}
|
|
8335
|
-
|
|
8336
|
-
// No package.json, default to container
|
|
8182
|
+
catch (parseError) {
|
|
8337
8183
|
serverType = 'container';
|
|
8338
8184
|
}
|
|
8339
8185
|
}
|
|
8340
|
-
}
|
|
8341
|
-
}
|
|
8342
|
-
const deployParams = {
|
|
8343
|
-
serverName: input.serverName,
|
|
8344
|
-
targetPath: targetPath,
|
|
8345
|
-
force: input.force,
|
|
8346
|
-
serverType: serverType,
|
|
8347
|
-
};
|
|
8348
|
-
// Add server configuration if provided
|
|
8349
|
-
if (input.serverConfig) {
|
|
8350
|
-
deployParams.serverConfig = input.serverConfig;
|
|
8351
|
-
}
|
|
8352
|
-
const result = await cloudrunService.deploy(deployParams);
|
|
8353
|
-
// Generate cloudbaserc.json configuration file
|
|
8354
|
-
const currentEnvId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
8355
|
-
const cloudbasercPath = path_1.default.join(targetPath, 'cloudbaserc.json');
|
|
8356
|
-
const cloudbasercContent = {
|
|
8357
|
-
envId: currentEnvId,
|
|
8358
|
-
cloudrun: {
|
|
8359
|
-
name: input.serverName
|
|
8360
|
-
}
|
|
8361
|
-
};
|
|
8362
|
-
try {
|
|
8363
|
-
fs_1.default.writeFileSync(cloudbasercPath, JSON.stringify(cloudbasercContent, null, 2));
|
|
8364
|
-
}
|
|
8365
|
-
catch (error) {
|
|
8366
|
-
// Ignore cloudbaserc.json creation errors
|
|
8367
|
-
}
|
|
8368
|
-
// Send deployment notification to CodeBuddy IDE
|
|
8369
|
-
try {
|
|
8370
|
-
// Query service details to get access URL
|
|
8371
|
-
let serviceUrl = "";
|
|
8372
|
-
try {
|
|
8373
|
-
const serviceDetails = await cloudrunService.detail({ serverName: input.serverName });
|
|
8374
|
-
// Extract access URL from service details
|
|
8375
|
-
// Priority: DefaultDomainName > CustomDomainName > PublicDomain > InternalDomain
|
|
8376
|
-
const details = serviceDetails; // Use any to access dynamic properties
|
|
8377
|
-
if (details?.BaseInfo?.DefaultDomainName) {
|
|
8378
|
-
// DefaultDomainName is already a complete URL (e.g., https://...)
|
|
8379
|
-
serviceUrl = details.BaseInfo.DefaultDomainName;
|
|
8380
|
-
}
|
|
8381
|
-
else if (details?.BaseInfo?.CustomDomainName) {
|
|
8382
|
-
// CustomDomainName might be a domain without protocol
|
|
8383
|
-
const customDomain = details.BaseInfo.CustomDomainName;
|
|
8384
|
-
serviceUrl = customDomain.startsWith('http') ? customDomain : `https://${customDomain}`;
|
|
8385
|
-
}
|
|
8386
|
-
else if (details?.BaseInfo?.PublicDomain) {
|
|
8387
|
-
serviceUrl = `https://${details.BaseInfo.PublicDomain}`;
|
|
8388
|
-
}
|
|
8389
|
-
else if (details?.BaseInfo?.InternalDomain) {
|
|
8390
|
-
serviceUrl = `https://${details.BaseInfo.InternalDomain}`;
|
|
8391
|
-
}
|
|
8392
|
-
else if (details?.AccessInfo?.PublicDomain) {
|
|
8393
|
-
serviceUrl = `https://${details.AccessInfo.PublicDomain}`;
|
|
8394
|
-
}
|
|
8395
8186
|
else {
|
|
8396
|
-
|
|
8187
|
+
// No package.json, default to container
|
|
8188
|
+
serverType = 'container';
|
|
8397
8189
|
}
|
|
8398
8190
|
}
|
|
8399
|
-
catch (detailErr) {
|
|
8400
|
-
// If query fails, continue with empty URL
|
|
8401
|
-
serviceUrl = "";
|
|
8402
|
-
}
|
|
8403
|
-
// Extract project name from targetPath
|
|
8404
|
-
const projectName = path_1.default.basename(targetPath);
|
|
8405
|
-
// Build console URL
|
|
8406
|
-
const consoleUrl = `https://tcb.cloud.tencent.com/dev?envId=${currentEnvId}#/platform-run/service/detail?serverName=${input.serverName}&tabId=overview&envId=${currentEnvId}`;
|
|
8407
|
-
// Send notification
|
|
8408
|
-
await (0, notification_js_1.sendDeployNotification)(server, {
|
|
8409
|
-
deployType: 'cloudrun',
|
|
8410
|
-
url: serviceUrl,
|
|
8411
|
-
projectId: currentEnvId,
|
|
8412
|
-
projectName: projectName,
|
|
8413
|
-
consoleUrl: consoleUrl
|
|
8414
|
-
});
|
|
8415
|
-
}
|
|
8416
|
-
catch (notifyErr) {
|
|
8417
|
-
// Notification failure should not affect deployment flow
|
|
8418
|
-
// Error is already logged in sendDeployNotification
|
|
8419
8191
|
}
|
|
8420
|
-
return {
|
|
8421
|
-
content: [
|
|
8422
|
-
{
|
|
8423
|
-
type: "text",
|
|
8424
|
-
text: JSON.stringify({
|
|
8425
|
-
success: true,
|
|
8426
|
-
data: {
|
|
8427
|
-
serviceName: input.serverName,
|
|
8428
|
-
status: 'deployed',
|
|
8429
|
-
deployPath: targetPath,
|
|
8430
|
-
serverType: serverType,
|
|
8431
|
-
cloudbasercGenerated: true
|
|
8432
|
-
},
|
|
8433
|
-
message: `Successfully deployed ${serverType} service '${input.serverName}' from ${targetPath}`
|
|
8434
|
-
}, null, 2)
|
|
8435
|
-
}
|
|
8436
|
-
]
|
|
8437
|
-
};
|
|
8438
8192
|
}
|
|
8439
|
-
|
|
8440
|
-
|
|
8441
|
-
|
|
8442
|
-
|
|
8443
|
-
|
|
8444
|
-
|
|
8445
|
-
|
|
8446
|
-
|
|
8193
|
+
const deployParams = {
|
|
8194
|
+
serverName: input.serverName,
|
|
8195
|
+
targetPath: targetPath,
|
|
8196
|
+
force: input.force,
|
|
8197
|
+
serverType: serverType,
|
|
8198
|
+
};
|
|
8199
|
+
// Add server configuration if provided
|
|
8200
|
+
if (input.serverConfig) {
|
|
8201
|
+
deployParams.serverConfig = input.serverConfig;
|
|
8202
|
+
}
|
|
8203
|
+
const result = await cloudrunService.deploy(deployParams);
|
|
8204
|
+
// Generate cloudbaserc.json configuration file
|
|
8205
|
+
const currentEnvId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
8206
|
+
const cloudbasercPath = path_1.default.join(targetPath, 'cloudbaserc.json');
|
|
8207
|
+
const cloudbasercContent = {
|
|
8208
|
+
envId: currentEnvId,
|
|
8209
|
+
cloudrun: {
|
|
8210
|
+
name: input.serverName
|
|
8447
8211
|
}
|
|
8448
|
-
|
|
8449
|
-
|
|
8450
|
-
|
|
8451
|
-
|
|
8452
|
-
|
|
8453
|
-
|
|
8454
|
-
|
|
8455
|
-
|
|
8456
|
-
|
|
8457
|
-
|
|
8458
|
-
|
|
8459
|
-
|
|
8460
|
-
|
|
8461
|
-
|
|
8462
|
-
|
|
8463
|
-
|
|
8464
|
-
|
|
8465
|
-
|
|
8466
|
-
|
|
8467
|
-
|
|
8468
|
-
|
|
8469
|
-
|
|
8470
|
-
|
|
8471
|
-
|
|
8472
|
-
|
|
8473
|
-
|
|
8212
|
+
};
|
|
8213
|
+
try {
|
|
8214
|
+
fs_1.default.writeFileSync(cloudbasercPath, JSON.stringify(cloudbasercContent, null, 2));
|
|
8215
|
+
}
|
|
8216
|
+
catch (error) {
|
|
8217
|
+
// Ignore cloudbaserc.json creation errors
|
|
8218
|
+
}
|
|
8219
|
+
// Send deployment notification to CodeBuddy IDE
|
|
8220
|
+
try {
|
|
8221
|
+
// Query service details to get access URL
|
|
8222
|
+
let serviceUrl = "";
|
|
8223
|
+
try {
|
|
8224
|
+
const serviceDetails = await cloudrunService.detail({ serverName: input.serverName });
|
|
8225
|
+
// Extract access URL from service details
|
|
8226
|
+
// Priority: DefaultDomainName > CustomDomainName > PublicDomain > InternalDomain
|
|
8227
|
+
const details = serviceDetails; // Use any to access dynamic properties
|
|
8228
|
+
if (details?.BaseInfo?.DefaultDomainName) {
|
|
8229
|
+
// DefaultDomainName is already a complete URL (e.g., https://...)
|
|
8230
|
+
serviceUrl = details.BaseInfo.DefaultDomainName;
|
|
8231
|
+
}
|
|
8232
|
+
else if (details?.BaseInfo?.CustomDomainName) {
|
|
8233
|
+
// CustomDomainName might be a domain without protocol
|
|
8234
|
+
const customDomain = details.BaseInfo.CustomDomainName;
|
|
8235
|
+
serviceUrl = customDomain.startsWith('http') ? customDomain : `https://${customDomain}`;
|
|
8236
|
+
}
|
|
8237
|
+
else if (details?.BaseInfo?.PublicDomain) {
|
|
8238
|
+
serviceUrl = `https://${details.BaseInfo.PublicDomain}`;
|
|
8239
|
+
}
|
|
8240
|
+
else if (details?.BaseInfo?.InternalDomain) {
|
|
8241
|
+
serviceUrl = `https://${details.BaseInfo.InternalDomain}`;
|
|
8242
|
+
}
|
|
8243
|
+
else if (details?.AccessInfo?.PublicDomain) {
|
|
8244
|
+
serviceUrl = `https://${details.AccessInfo.PublicDomain}`;
|
|
8474
8245
|
}
|
|
8475
|
-
|
|
8476
|
-
|
|
8477
|
-
runningProcesses.delete(input.serverName);
|
|
8246
|
+
else {
|
|
8247
|
+
serviceUrl = ""; // URL not available
|
|
8478
8248
|
}
|
|
8479
8249
|
}
|
|
8480
|
-
|
|
8481
|
-
|
|
8482
|
-
|
|
8483
|
-
|
|
8484
|
-
|
|
8485
|
-
|
|
8486
|
-
|
|
8487
|
-
|
|
8488
|
-
|
|
8489
|
-
|
|
8490
|
-
|
|
8491
|
-
|
|
8492
|
-
|
|
8493
|
-
|
|
8494
|
-
|
|
8495
|
-
|
|
8496
|
-
|
|
8497
|
-
|
|
8250
|
+
catch (detailErr) {
|
|
8251
|
+
// If query fails, continue with empty URL
|
|
8252
|
+
serviceUrl = "";
|
|
8253
|
+
}
|
|
8254
|
+
// Extract project name from targetPath
|
|
8255
|
+
const projectName = path_1.default.basename(targetPath);
|
|
8256
|
+
// Build console URL
|
|
8257
|
+
const consoleUrl = `https://tcb.cloud.tencent.com/dev?envId=${currentEnvId}#/platform-run/service/detail?serverName=${input.serverName}&tabId=overview&envId=${currentEnvId}`;
|
|
8258
|
+
// Send notification
|
|
8259
|
+
await (0, notification_js_1.sendDeployNotification)(server, {
|
|
8260
|
+
deployType: 'cloudrun',
|
|
8261
|
+
url: serviceUrl,
|
|
8262
|
+
projectId: currentEnvId,
|
|
8263
|
+
projectName: projectName,
|
|
8264
|
+
consoleUrl: consoleUrl
|
|
8265
|
+
});
|
|
8266
|
+
}
|
|
8267
|
+
catch (notifyErr) {
|
|
8268
|
+
// Notification failure should not affect deployment flow
|
|
8269
|
+
// Error is already logged in sendDeployNotification
|
|
8270
|
+
}
|
|
8271
|
+
return {
|
|
8272
|
+
content: [
|
|
8273
|
+
{
|
|
8274
|
+
type: "text",
|
|
8275
|
+
text: JSON.stringify({
|
|
8276
|
+
success: true,
|
|
8277
|
+
data: {
|
|
8278
|
+
serviceName: input.serverName,
|
|
8279
|
+
status: 'deployed',
|
|
8280
|
+
deployPath: targetPath,
|
|
8281
|
+
serverType: serverType,
|
|
8282
|
+
cloudbasercGenerated: true
|
|
8283
|
+
},
|
|
8284
|
+
message: `Successfully deployed ${serverType} service '${input.serverName}' from ${targetPath}`
|
|
8285
|
+
}, null, 2)
|
|
8286
|
+
}
|
|
8287
|
+
]
|
|
8288
|
+
};
|
|
8289
|
+
}
|
|
8290
|
+
case 'run': {
|
|
8291
|
+
if (!targetPath) {
|
|
8292
|
+
throw new Error("targetPath is required for run operation");
|
|
8293
|
+
}
|
|
8294
|
+
// Do not support container services locally: basic heuristic - if Dockerfile exists, treat as container
|
|
8295
|
+
const dockerfilePath = path_1.default.join(targetPath, 'Dockerfile');
|
|
8296
|
+
if (fs_1.default.existsSync(dockerfilePath)) {
|
|
8297
|
+
throw new Error("Local run is only supported for function-type CloudRun services. Container services are not supported.");
|
|
8298
|
+
}
|
|
8299
|
+
// Check if this is an Agent project
|
|
8300
|
+
const isAgent = checkIfAgentProject(targetPath);
|
|
8301
|
+
const runMode = input.runOptions?.runMode || (isAgent ? 'agent' : 'normal');
|
|
8302
|
+
// Check if service is already running and verify process exists
|
|
8303
|
+
if (runningProcesses.has(input.serverName)) {
|
|
8304
|
+
const existingPid = runningProcesses.get(input.serverName);
|
|
8305
|
+
try {
|
|
8306
|
+
// Check if process actually exists
|
|
8307
|
+
process.kill(existingPid, 0);
|
|
8308
|
+
return {
|
|
8309
|
+
content: [
|
|
8310
|
+
{
|
|
8311
|
+
type: "text",
|
|
8312
|
+
text: JSON.stringify({
|
|
8313
|
+
success: true,
|
|
8314
|
+
data: {
|
|
8315
|
+
serviceName: input.serverName,
|
|
8316
|
+
status: 'running',
|
|
8317
|
+
pid: existingPid,
|
|
8318
|
+
cwd: targetPath
|
|
8319
|
+
},
|
|
8320
|
+
message: `Service '${input.serverName}' is already running locally (pid=${existingPid})`
|
|
8321
|
+
}, null, 2)
|
|
8322
|
+
}
|
|
8323
|
+
]
|
|
8324
|
+
};
|
|
8325
|
+
}
|
|
8326
|
+
catch (error) {
|
|
8327
|
+
// Process doesn't exist, remove from tracking
|
|
8328
|
+
runningProcesses.delete(input.serverName);
|
|
8329
|
+
}
|
|
8330
|
+
}
|
|
8331
|
+
const runPort = input.runOptions?.port ?? 3000;
|
|
8332
|
+
const extraEnv = input.runOptions?.envParams ?? {};
|
|
8333
|
+
// Set environment variables for functions-framework
|
|
8334
|
+
const env = {
|
|
8335
|
+
...process.env,
|
|
8336
|
+
PORT: String(runPort),
|
|
8337
|
+
...extraEnv,
|
|
8338
|
+
// Add functions-framework specific environment variables
|
|
8339
|
+
ENABLE_CORS: 'true',
|
|
8340
|
+
ALLOWED_ORIGINS: '*'
|
|
8341
|
+
};
|
|
8342
|
+
// Choose execution method based on run mode
|
|
8343
|
+
let child;
|
|
8344
|
+
let command;
|
|
8345
|
+
if (runMode === 'agent') {
|
|
8346
|
+
// For Agent mode, use a different approach since functions-framework doesn't support Agent mode
|
|
8347
|
+
// We'll use a custom script that sets up the Agent environment
|
|
8348
|
+
command = `node -e "
|
|
8498
8349
|
const { runCLI } = require('@cloudbase/functions-framework');
|
|
8499
8350
|
process.env.PORT = '${runPort}';
|
|
8500
8351
|
process.env.ENABLE_CORS = 'true';
|
|
@@ -8503,16 +8354,16 @@ for await (let x of res.textStream) {
|
|
|
8503
8354
|
${Object.entries(extraEnv).map(([key, value]) => `process.env.${key} = '${value}';`).join('\n')}
|
|
8504
8355
|
runCLI();
|
|
8505
8356
|
"`;
|
|
8506
|
-
|
|
8507
|
-
|
|
8508
|
-
|
|
8509
|
-
|
|
8510
|
-
|
|
8511
|
-
|
|
8512
|
-
|
|
8513
|
-
|
|
8514
|
-
|
|
8515
|
-
|
|
8357
|
+
child = (0, child_process_1.spawn)(process.execPath, ['-e', command], {
|
|
8358
|
+
cwd: targetPath,
|
|
8359
|
+
env,
|
|
8360
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
8361
|
+
detached: true
|
|
8362
|
+
});
|
|
8363
|
+
}
|
|
8364
|
+
else {
|
|
8365
|
+
// Normal function mode
|
|
8366
|
+
command = `node -e "
|
|
8516
8367
|
const { runCLI } = require('@cloudbase/functions-framework');
|
|
8517
8368
|
process.env.PORT = '${runPort}';
|
|
8518
8369
|
process.env.ENABLE_CORS = 'true';
|
|
@@ -8520,182 +8371,167 @@ for await (let x of res.textStream) {
|
|
|
8520
8371
|
${Object.entries(extraEnv).map(([key, value]) => `process.env.${key} = '${value}';`).join('\n')}
|
|
8521
8372
|
runCLI();
|
|
8522
8373
|
"`;
|
|
8523
|
-
|
|
8524
|
-
|
|
8525
|
-
|
|
8526
|
-
|
|
8527
|
-
|
|
8528
|
-
});
|
|
8529
|
-
}
|
|
8530
|
-
// Handle process exit to clean up tracking
|
|
8531
|
-
child.on('exit', (code, signal) => {
|
|
8532
|
-
runningProcesses.delete(input.serverName);
|
|
8533
|
-
});
|
|
8534
|
-
child.on('error', (error) => {
|
|
8535
|
-
runningProcesses.delete(input.serverName);
|
|
8374
|
+
child = (0, child_process_1.spawn)(process.execPath, ['-e', command], {
|
|
8375
|
+
cwd: targetPath,
|
|
8376
|
+
env,
|
|
8377
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
8378
|
+
detached: true
|
|
8536
8379
|
});
|
|
8537
|
-
child.unref();
|
|
8538
|
-
if (typeof child.pid !== 'number') {
|
|
8539
|
-
throw new Error('Failed to start local process: PID is undefined.');
|
|
8540
|
-
}
|
|
8541
|
-
runningProcesses.set(input.serverName, child.pid);
|
|
8542
|
-
return {
|
|
8543
|
-
content: [
|
|
8544
|
-
{
|
|
8545
|
-
type: "text",
|
|
8546
|
-
text: JSON.stringify({
|
|
8547
|
-
success: true,
|
|
8548
|
-
data: {
|
|
8549
|
-
serviceName: input.serverName,
|
|
8550
|
-
status: 'running',
|
|
8551
|
-
pid: child.pid,
|
|
8552
|
-
port: runPort,
|
|
8553
|
-
runMode: runMode,
|
|
8554
|
-
isAgent: isAgent,
|
|
8555
|
-
command: command,
|
|
8556
|
-
cwd: targetPath
|
|
8557
|
-
},
|
|
8558
|
-
message: `Started local run for ${runMode} service '${input.serverName}' on port ${runPort} (pid=${child.pid})`
|
|
8559
|
-
}, null, 2)
|
|
8560
|
-
}
|
|
8561
|
-
]
|
|
8562
|
-
};
|
|
8563
8380
|
}
|
|
8564
|
-
|
|
8565
|
-
|
|
8566
|
-
|
|
8567
|
-
|
|
8568
|
-
|
|
8569
|
-
|
|
8570
|
-
|
|
8571
|
-
|
|
8572
|
-
|
|
8573
|
-
|
|
8574
|
-
|
|
8575
|
-
|
|
8576
|
-
|
|
8577
|
-
|
|
8578
|
-
|
|
8381
|
+
// Handle process exit to clean up tracking
|
|
8382
|
+
child.on('exit', (code, signal) => {
|
|
8383
|
+
runningProcesses.delete(input.serverName);
|
|
8384
|
+
});
|
|
8385
|
+
child.on('error', (error) => {
|
|
8386
|
+
runningProcesses.delete(input.serverName);
|
|
8387
|
+
});
|
|
8388
|
+
child.unref();
|
|
8389
|
+
if (typeof child.pid !== 'number') {
|
|
8390
|
+
throw new Error('Failed to start local process: PID is undefined.');
|
|
8391
|
+
}
|
|
8392
|
+
runningProcesses.set(input.serverName, child.pid);
|
|
8393
|
+
return {
|
|
8394
|
+
content: [
|
|
8395
|
+
{
|
|
8396
|
+
type: "text",
|
|
8397
|
+
text: JSON.stringify({
|
|
8398
|
+
success: true,
|
|
8399
|
+
data: {
|
|
8400
|
+
serviceName: input.serverName,
|
|
8401
|
+
status: 'running',
|
|
8402
|
+
pid: child.pid,
|
|
8403
|
+
port: runPort,
|
|
8404
|
+
runMode: runMode,
|
|
8405
|
+
isAgent: isAgent,
|
|
8406
|
+
command: command,
|
|
8407
|
+
cwd: targetPath
|
|
8408
|
+
},
|
|
8409
|
+
message: `Started local run for ${runMode} service '${input.serverName}' on port ${runPort} (pid=${child.pid})`
|
|
8410
|
+
}, null, 2)
|
|
8579
8411
|
}
|
|
8580
|
-
|
|
8581
|
-
|
|
8582
|
-
|
|
8583
|
-
|
|
8584
|
-
|
|
8585
|
-
|
|
8586
|
-
}
|
|
8587
|
-
return {
|
|
8588
|
-
content: [
|
|
8589
|
-
{
|
|
8590
|
-
type: "text",
|
|
8591
|
-
text: JSON.stringify({
|
|
8592
|
-
success: true,
|
|
8593
|
-
data: {
|
|
8594
|
-
serviceName: input.serverName,
|
|
8595
|
-
downloadPath: targetPath,
|
|
8596
|
-
filesCount: 0,
|
|
8597
|
-
cloudbasercGenerated: true
|
|
8598
|
-
},
|
|
8599
|
-
message: `Successfully downloaded service '${input.serverName}' to ${targetPath}`
|
|
8600
|
-
}, null, 2)
|
|
8601
|
-
}
|
|
8602
|
-
]
|
|
8603
|
-
};
|
|
8412
|
+
]
|
|
8413
|
+
};
|
|
8414
|
+
}
|
|
8415
|
+
case 'download': {
|
|
8416
|
+
if (!targetPath) {
|
|
8417
|
+
throw new Error("targetPath is required for download operation");
|
|
8604
8418
|
}
|
|
8605
|
-
|
|
8606
|
-
|
|
8607
|
-
|
|
8608
|
-
|
|
8609
|
-
|
|
8610
|
-
|
|
8611
|
-
|
|
8612
|
-
|
|
8613
|
-
|
|
8614
|
-
|
|
8615
|
-
|
|
8616
|
-
}
|
|
8617
|
-
]
|
|
8618
|
-
};
|
|
8419
|
+
const result = await cloudrunService.download({
|
|
8420
|
+
serverName: input.serverName,
|
|
8421
|
+
targetPath: targetPath,
|
|
8422
|
+
});
|
|
8423
|
+
// Generate cloudbaserc.json configuration file
|
|
8424
|
+
const currentEnvId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
8425
|
+
const cloudbasercPath = path_1.default.join(targetPath, 'cloudbaserc.json');
|
|
8426
|
+
const cloudbasercContent = {
|
|
8427
|
+
envId: currentEnvId,
|
|
8428
|
+
cloudrun: {
|
|
8429
|
+
name: input.serverName
|
|
8619
8430
|
}
|
|
8620
|
-
|
|
8621
|
-
|
|
8622
|
-
|
|
8623
|
-
return {
|
|
8624
|
-
content: [
|
|
8625
|
-
{
|
|
8626
|
-
type: "text",
|
|
8627
|
-
text: JSON.stringify({
|
|
8628
|
-
success: true,
|
|
8629
|
-
data: {
|
|
8630
|
-
serviceName: input.serverName,
|
|
8631
|
-
status: 'deleted'
|
|
8632
|
-
},
|
|
8633
|
-
message: `Successfully deleted service '${input.serverName}'`
|
|
8634
|
-
}, null, 2)
|
|
8635
|
-
}
|
|
8636
|
-
]
|
|
8637
|
-
};
|
|
8431
|
+
};
|
|
8432
|
+
try {
|
|
8433
|
+
fs_1.default.writeFileSync(cloudbasercPath, JSON.stringify(cloudbasercContent, null, 2));
|
|
8638
8434
|
}
|
|
8639
|
-
|
|
8640
|
-
|
|
8641
|
-
|
|
8642
|
-
|
|
8643
|
-
|
|
8644
|
-
|
|
8645
|
-
|
|
8646
|
-
|
|
8647
|
-
|
|
8648
|
-
|
|
8649
|
-
|
|
8650
|
-
|
|
8651
|
-
|
|
8652
|
-
|
|
8653
|
-
|
|
8654
|
-
|
|
8435
|
+
catch (error) {
|
|
8436
|
+
// Ignore cloudbaserc.json creation errors
|
|
8437
|
+
}
|
|
8438
|
+
return {
|
|
8439
|
+
content: [
|
|
8440
|
+
{
|
|
8441
|
+
type: "text",
|
|
8442
|
+
text: JSON.stringify({
|
|
8443
|
+
success: true,
|
|
8444
|
+
data: {
|
|
8445
|
+
serviceName: input.serverName,
|
|
8446
|
+
downloadPath: targetPath,
|
|
8447
|
+
filesCount: 0,
|
|
8448
|
+
cloudbasercGenerated: true
|
|
8449
|
+
},
|
|
8450
|
+
message: `Successfully downloaded service '${input.serverName}' to ${targetPath}`
|
|
8451
|
+
}, null, 2)
|
|
8655
8452
|
}
|
|
8656
|
-
|
|
8657
|
-
|
|
8658
|
-
|
|
8659
|
-
|
|
8660
|
-
|
|
8661
|
-
// Ignore cloudbaserc.json creation errors
|
|
8662
|
-
}
|
|
8453
|
+
]
|
|
8454
|
+
};
|
|
8455
|
+
}
|
|
8456
|
+
case 'delete': {
|
|
8457
|
+
if (!input.force) {
|
|
8663
8458
|
return {
|
|
8664
8459
|
content: [
|
|
8665
8460
|
{
|
|
8666
8461
|
type: "text",
|
|
8667
8462
|
text: JSON.stringify({
|
|
8668
|
-
success:
|
|
8669
|
-
|
|
8670
|
-
|
|
8671
|
-
template: input.template,
|
|
8672
|
-
initPath: targetPath,
|
|
8673
|
-
projectDir: result.projectDir || path_1.default.join(targetPath, input.serverName),
|
|
8674
|
-
cloudbasercGenerated: true
|
|
8675
|
-
},
|
|
8676
|
-
message: `Successfully initialized service '${input.serverName}' with template '${input.template}' at ${targetPath}`
|
|
8463
|
+
success: false,
|
|
8464
|
+
error: "Delete operation requires confirmation",
|
|
8465
|
+
message: "Please set force: true to confirm deletion of the service. This action cannot be undone."
|
|
8677
8466
|
}, null, 2)
|
|
8678
8467
|
}
|
|
8679
8468
|
]
|
|
8680
8469
|
};
|
|
8681
8470
|
}
|
|
8682
|
-
|
|
8683
|
-
|
|
8471
|
+
const result = await cloudrunService.delete({
|
|
8472
|
+
serverName: input.serverName,
|
|
8473
|
+
});
|
|
8474
|
+
return {
|
|
8475
|
+
content: [
|
|
8476
|
+
{
|
|
8477
|
+
type: "text",
|
|
8478
|
+
text: JSON.stringify({
|
|
8479
|
+
success: true,
|
|
8480
|
+
data: {
|
|
8481
|
+
serviceName: input.serverName,
|
|
8482
|
+
status: 'deleted'
|
|
8483
|
+
},
|
|
8484
|
+
message: `Successfully deleted service '${input.serverName}'`
|
|
8485
|
+
}, null, 2)
|
|
8486
|
+
}
|
|
8487
|
+
]
|
|
8488
|
+
};
|
|
8684
8489
|
}
|
|
8685
|
-
|
|
8686
|
-
|
|
8687
|
-
|
|
8688
|
-
|
|
8689
|
-
|
|
8690
|
-
|
|
8691
|
-
|
|
8692
|
-
|
|
8693
|
-
|
|
8694
|
-
|
|
8695
|
-
|
|
8490
|
+
case 'init': {
|
|
8491
|
+
if (!targetPath) {
|
|
8492
|
+
throw new Error("targetPath is required for init operation");
|
|
8493
|
+
}
|
|
8494
|
+
const result = await cloudrunService.init({
|
|
8495
|
+
serverName: input.serverName,
|
|
8496
|
+
targetPath: targetPath,
|
|
8497
|
+
template: input.template,
|
|
8498
|
+
});
|
|
8499
|
+
// Generate cloudbaserc.json configuration file
|
|
8500
|
+
const currentEnvId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
8501
|
+
const cloudbasercPath = path_1.default.join(targetPath, input.serverName, 'cloudbaserc.json');
|
|
8502
|
+
const cloudbasercContent = {
|
|
8503
|
+
envId: currentEnvId,
|
|
8504
|
+
cloudrun: {
|
|
8505
|
+
name: input.serverName
|
|
8696
8506
|
}
|
|
8697
|
-
|
|
8698
|
-
|
|
8507
|
+
};
|
|
8508
|
+
try {
|
|
8509
|
+
fs_1.default.writeFileSync(cloudbasercPath, JSON.stringify(cloudbasercContent, null, 2));
|
|
8510
|
+
}
|
|
8511
|
+
catch (error) {
|
|
8512
|
+
// Ignore cloudbaserc.json creation errors
|
|
8513
|
+
}
|
|
8514
|
+
return {
|
|
8515
|
+
content: [
|
|
8516
|
+
{
|
|
8517
|
+
type: "text",
|
|
8518
|
+
text: JSON.stringify({
|
|
8519
|
+
success: true,
|
|
8520
|
+
data: {
|
|
8521
|
+
serviceName: input.serverName,
|
|
8522
|
+
template: input.template,
|
|
8523
|
+
initPath: targetPath,
|
|
8524
|
+
projectDir: result.projectDir || path_1.default.join(targetPath, input.serverName),
|
|
8525
|
+
cloudbasercGenerated: true
|
|
8526
|
+
},
|
|
8527
|
+
message: `Successfully initialized service '${input.serverName}' with template '${input.template}' at ${targetPath}`
|
|
8528
|
+
}, null, 2)
|
|
8529
|
+
}
|
|
8530
|
+
]
|
|
8531
|
+
};
|
|
8532
|
+
}
|
|
8533
|
+
default:
|
|
8534
|
+
throw new Error(`Unsupported action: ${input.action}`);
|
|
8699
8535
|
}
|
|
8700
8536
|
});
|
|
8701
8537
|
}
|
|
@@ -8770,7 +8606,7 @@ class TelemetryReporter {
|
|
|
8770
8606
|
const nodeVersion = process.version; // Node.js版本
|
|
8771
8607
|
const arch = os_1.default.arch(); // 系统架构
|
|
8772
8608
|
// 从构建时注入的版本号获取MCP版本信息
|
|
8773
|
-
const mcpVersion = process.env.npm_package_version || "2.
|
|
8609
|
+
const mcpVersion = process.env.npm_package_version || "2.10.0" || 0;
|
|
8774
8610
|
return {
|
|
8775
8611
|
userAgent: `${osType} ${osRelease} ${arch} ${nodeVersion} CloudBase-MCP/${mcpVersion}`,
|
|
8776
8612
|
deviceId: this.deviceId,
|
|
@@ -10203,7 +10039,7 @@ function registerSetupTools(server) {
|
|
|
10203
10039
|
title: "下载项目模板",
|
|
10204
10040
|
description: `自动下载并部署CloudBase项目模板。⚠️ **MANDATORY FOR NEW PROJECTS** ⚠️
|
|
10205
10041
|
|
|
10206
|
-
**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- 其他IDE类型见下方列表\n\n注意:如果未传入 ide 参数且无法从环境变量检测到 IDE,将提示错误并要求传入 ide 参数\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- kiro: Kiro AI编辑器\n- aider: Aider AI编辑器\n\n特别说明:\n- rules 模板会自动包含当前 mcp 版本号信息(版本号:${ true ? "2.
|
|
10042
|
+
**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- 其他IDE类型见下方列表\n\n注意:如果未传入 ide 参数且无法从环境变量检测到 IDE,将提示错误并要求传入 ide 参数\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- kiro: Kiro AI编辑器\n- aider: Aider AI编辑器\n\n特别说明:\n- rules 模板会自动包含当前 mcp 版本号信息(版本号:${ true ? "2.10.0" : 0}),便于后续维护和版本追踪\n- 下载 rules 模板时,如果项目中已存在 README.md 文件,系统会自动保护该文件不被覆盖(除非设置 overwrite=true)`,
|
|
10207
10043
|
inputSchema: {
|
|
10208
10044
|
template: zod_1.z
|
|
10209
10045
|
.enum(["react", "vue", "miniprogram", "uniapp", "rules"])
|
|
@@ -12470,90 +12306,70 @@ function registerSecurityRuleTools(server) {
|
|
|
12470
12306
|
},
|
|
12471
12307
|
}, async ({ resourceType, resourceId }) => {
|
|
12472
12308
|
const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
12473
|
-
|
|
12474
|
-
|
|
12475
|
-
|
|
12476
|
-
|
|
12477
|
-
|
|
12478
|
-
|
|
12479
|
-
|
|
12480
|
-
|
|
12481
|
-
|
|
12482
|
-
|
|
12483
|
-
|
|
12484
|
-
});
|
|
12485
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12486
|
-
}
|
|
12487
|
-
else if (resourceType === "function") {
|
|
12488
|
-
// 查询云函数安全规则
|
|
12489
|
-
result = await cloudbase.commonService().call({
|
|
12490
|
-
Action: "DescribeSecurityRule",
|
|
12491
|
-
Param: {
|
|
12492
|
-
ResourceType: "FUNCTION",
|
|
12493
|
-
EnvId: envId,
|
|
12494
|
-
},
|
|
12495
|
-
});
|
|
12496
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12497
|
-
}
|
|
12498
|
-
else if (resourceType === "storage") {
|
|
12499
|
-
// 查询存储安全规则
|
|
12500
|
-
result = await cloudbase.commonService().call({
|
|
12501
|
-
Action: "DescribeStorageSafeRule",
|
|
12502
|
-
Param: {
|
|
12503
|
-
Bucket: resourceId,
|
|
12504
|
-
EnvId: envId,
|
|
12505
|
-
},
|
|
12506
|
-
});
|
|
12507
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12508
|
-
}
|
|
12509
|
-
else if (resourceType === "sqlDatabase") {
|
|
12510
|
-
// TODO: 考虑是否有支持指定其他 instance、schema 的需求
|
|
12511
|
-
const instanceId = "default";
|
|
12512
|
-
const schema = envId;
|
|
12513
|
-
const tableName = resourceId;
|
|
12514
|
-
result = await cloudbase.commonService("lowcode").call({
|
|
12515
|
-
Action: "DescribeDataSourceBasicPolicy",
|
|
12516
|
-
Param: {
|
|
12517
|
-
EnvId: envId,
|
|
12518
|
-
ResourceType: "table",
|
|
12519
|
-
ResourceId: `${instanceId}#${schema}#${tableName}`,
|
|
12520
|
-
RoleIdentityList: ["allUser"],
|
|
12521
|
-
},
|
|
12522
|
-
});
|
|
12523
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12524
|
-
}
|
|
12525
|
-
else {
|
|
12526
|
-
throw new Error(`不支持的资源类型: ${resourceType}`);
|
|
12527
|
-
}
|
|
12528
|
-
return {
|
|
12529
|
-
content: [
|
|
12530
|
-
{
|
|
12531
|
-
type: "text",
|
|
12532
|
-
text: JSON.stringify({
|
|
12533
|
-
success: true,
|
|
12534
|
-
aclTag: result.AclTag,
|
|
12535
|
-
rule: result.Rule ?? null,
|
|
12536
|
-
raw: result,
|
|
12537
|
-
message: "安全规则读取成功",
|
|
12538
|
-
}, null, 2),
|
|
12539
|
-
},
|
|
12540
|
-
],
|
|
12541
|
-
};
|
|
12309
|
+
const cloudbase = await getManager();
|
|
12310
|
+
let result;
|
|
12311
|
+
if (resourceType === "noSqlDatabase") {
|
|
12312
|
+
result = await cloudbase.commonService().call({
|
|
12313
|
+
Action: "DescribeSafeRule",
|
|
12314
|
+
Param: {
|
|
12315
|
+
CollectionName: resourceId,
|
|
12316
|
+
EnvId: envId,
|
|
12317
|
+
},
|
|
12318
|
+
});
|
|
12319
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12542
12320
|
}
|
|
12543
|
-
|
|
12544
|
-
|
|
12545
|
-
|
|
12546
|
-
|
|
12547
|
-
|
|
12548
|
-
|
|
12549
|
-
|
|
12550
|
-
|
|
12551
|
-
|
|
12552
|
-
|
|
12553
|
-
|
|
12554
|
-
|
|
12555
|
-
|
|
12321
|
+
else if (resourceType === "function") {
|
|
12322
|
+
result = await cloudbase.commonService().call({
|
|
12323
|
+
Action: "DescribeSecurityRule",
|
|
12324
|
+
Param: {
|
|
12325
|
+
ResourceType: "FUNCTION",
|
|
12326
|
+
EnvId: envId,
|
|
12327
|
+
},
|
|
12328
|
+
});
|
|
12329
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12330
|
+
}
|
|
12331
|
+
else if (resourceType === "storage") {
|
|
12332
|
+
result = await cloudbase.commonService().call({
|
|
12333
|
+
Action: "DescribeStorageSafeRule",
|
|
12334
|
+
Param: {
|
|
12335
|
+
Bucket: resourceId,
|
|
12336
|
+
EnvId: envId,
|
|
12337
|
+
},
|
|
12338
|
+
});
|
|
12339
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12340
|
+
}
|
|
12341
|
+
else if (resourceType === "sqlDatabase") {
|
|
12342
|
+
const instanceId = "default";
|
|
12343
|
+
const schema = envId;
|
|
12344
|
+
const tableName = resourceId;
|
|
12345
|
+
result = await cloudbase.commonService("lowcode").call({
|
|
12346
|
+
Action: "DescribeDataSourceBasicPolicy",
|
|
12347
|
+
Param: {
|
|
12348
|
+
EnvId: envId,
|
|
12349
|
+
ResourceType: "table",
|
|
12350
|
+
ResourceId: `${instanceId}#${schema}#${tableName}`,
|
|
12351
|
+
RoleIdentityList: ["allUser"],
|
|
12352
|
+
},
|
|
12353
|
+
});
|
|
12354
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12355
|
+
}
|
|
12356
|
+
else {
|
|
12357
|
+
throw new Error(`不支持的资源类型: ${resourceType}`);
|
|
12556
12358
|
}
|
|
12359
|
+
return {
|
|
12360
|
+
content: [
|
|
12361
|
+
{
|
|
12362
|
+
type: "text",
|
|
12363
|
+
text: JSON.stringify({
|
|
12364
|
+
success: true,
|
|
12365
|
+
aclTag: result.AclTag,
|
|
12366
|
+
rule: result.Rule ?? null,
|
|
12367
|
+
raw: result,
|
|
12368
|
+
message: "安全规则读取成功",
|
|
12369
|
+
}, null, 2),
|
|
12370
|
+
},
|
|
12371
|
+
],
|
|
12372
|
+
};
|
|
12557
12373
|
});
|
|
12558
12374
|
// 写入安全规则 Tool
|
|
12559
12375
|
server.registerTool?.(exports.WRITE_SECURITY_RULE, {
|
|
@@ -12580,154 +12396,138 @@ function registerSecurityRuleTools(server) {
|
|
|
12580
12396
|
category: "security-rule",
|
|
12581
12397
|
},
|
|
12582
12398
|
}, async ({ resourceType, resourceId, aclTag, rule }) => {
|
|
12583
|
-
|
|
12584
|
-
|
|
12585
|
-
|
|
12586
|
-
|
|
12587
|
-
if (
|
|
12588
|
-
if (aclTag === "CUSTOM") {
|
|
12589
|
-
if (!rule)
|
|
12590
|
-
throw new Error("noSQL 数据库自定义安全规则(CUSTOM)必须提供 rule 字段");
|
|
12591
|
-
result = await cloudbase.commonService().call({
|
|
12592
|
-
Action: "ModifySafeRule",
|
|
12593
|
-
Param: {
|
|
12594
|
-
CollectionName: resourceId,
|
|
12595
|
-
EnvId: envId,
|
|
12596
|
-
AclTag: aclTag,
|
|
12597
|
-
Rule: rule,
|
|
12598
|
-
},
|
|
12599
|
-
});
|
|
12600
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12601
|
-
}
|
|
12602
|
-
else {
|
|
12603
|
-
result = await cloudbase.commonService().call({
|
|
12604
|
-
Action: "ModifyDatabaseACL",
|
|
12605
|
-
Param: {
|
|
12606
|
-
CollectionName: resourceId,
|
|
12607
|
-
EnvId: envId,
|
|
12608
|
-
AclTag: aclTag,
|
|
12609
|
-
},
|
|
12610
|
-
});
|
|
12611
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12612
|
-
}
|
|
12613
|
-
}
|
|
12614
|
-
else if (resourceType === "function") {
|
|
12615
|
-
if (aclTag !== "CUSTOM")
|
|
12616
|
-
throw new Error("云函数安全规则仅支持 CUSTOM 权限类别");
|
|
12399
|
+
const cloudbase = await getManager();
|
|
12400
|
+
const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
12401
|
+
let result;
|
|
12402
|
+
if (resourceType === "noSqlDatabase") {
|
|
12403
|
+
if (aclTag === "CUSTOM") {
|
|
12617
12404
|
if (!rule)
|
|
12618
|
-
throw new Error("
|
|
12405
|
+
throw new Error("noSQL 数据库自定义安全规则(CUSTOM)必须提供 rule 字段");
|
|
12619
12406
|
result = await cloudbase.commonService().call({
|
|
12620
|
-
Action: "
|
|
12407
|
+
Action: "ModifySafeRule",
|
|
12621
12408
|
Param: {
|
|
12622
|
-
|
|
12409
|
+
CollectionName: resourceId,
|
|
12623
12410
|
EnvId: envId,
|
|
12624
|
-
|
|
12411
|
+
AclTag: aclTag,
|
|
12625
12412
|
Rule: rule,
|
|
12626
12413
|
},
|
|
12627
12414
|
});
|
|
12628
12415
|
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12629
12416
|
}
|
|
12630
|
-
else
|
|
12631
|
-
|
|
12632
|
-
|
|
12633
|
-
|
|
12634
|
-
|
|
12635
|
-
|
|
12636
|
-
|
|
12637
|
-
|
|
12638
|
-
|
|
12639
|
-
|
|
12640
|
-
Rule: rule,
|
|
12641
|
-
},
|
|
12642
|
-
});
|
|
12643
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12644
|
-
}
|
|
12645
|
-
else {
|
|
12646
|
-
result = await cloudbase.commonService().call({
|
|
12647
|
-
Action: "ModifyStorageSafeRule",
|
|
12648
|
-
Param: {
|
|
12649
|
-
Bucket: resourceId,
|
|
12650
|
-
EnvId: envId,
|
|
12651
|
-
AclTag: aclTag,
|
|
12652
|
-
},
|
|
12653
|
-
});
|
|
12654
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12655
|
-
}
|
|
12417
|
+
else {
|
|
12418
|
+
result = await cloudbase.commonService().call({
|
|
12419
|
+
Action: "ModifyDatabaseACL",
|
|
12420
|
+
Param: {
|
|
12421
|
+
CollectionName: resourceId,
|
|
12422
|
+
EnvId: envId,
|
|
12423
|
+
AclTag: aclTag,
|
|
12424
|
+
},
|
|
12425
|
+
});
|
|
12426
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12656
12427
|
}
|
|
12657
|
-
|
|
12658
|
-
|
|
12659
|
-
|
|
12660
|
-
|
|
12661
|
-
|
|
12662
|
-
|
|
12663
|
-
|
|
12664
|
-
|
|
12665
|
-
|
|
12666
|
-
|
|
12667
|
-
|
|
12668
|
-
"
|
|
12669
|
-
|
|
12670
|
-
|
|
12671
|
-
|
|
12672
|
-
|
|
12673
|
-
|
|
12674
|
-
|
|
12675
|
-
|
|
12676
|
-
|
|
12677
|
-
|
|
12678
|
-
|
|
12679
|
-
|
|
12680
|
-
result = await cloudbase.commonService("lowcode").call({
|
|
12681
|
-
Action: "BatchCreateResourcePolicy",
|
|
12428
|
+
}
|
|
12429
|
+
else if (resourceType === "function") {
|
|
12430
|
+
if (aclTag !== "CUSTOM")
|
|
12431
|
+
throw new Error("云函数安全规则仅支持 CUSTOM 权限类别");
|
|
12432
|
+
if (!rule)
|
|
12433
|
+
throw new Error("云函数自定义安全规则(CUSTOM)必须提供 rule 字段");
|
|
12434
|
+
result = await cloudbase.commonService().call({
|
|
12435
|
+
Action: "ModifySecurityRule",
|
|
12436
|
+
Param: {
|
|
12437
|
+
AclTag: aclTag,
|
|
12438
|
+
EnvId: envId,
|
|
12439
|
+
ResourceType: "FUNCTION",
|
|
12440
|
+
Rule: rule,
|
|
12441
|
+
},
|
|
12442
|
+
});
|
|
12443
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12444
|
+
}
|
|
12445
|
+
else if (resourceType === "storage") {
|
|
12446
|
+
if (aclTag === "CUSTOM") {
|
|
12447
|
+
if (!rule)
|
|
12448
|
+
throw new Error("存储自定义安全规则(CUSTOM)必须提供 rule 字段");
|
|
12449
|
+
result = await cloudbase.commonService().call({
|
|
12450
|
+
Action: "ModifyStorageSafeRule",
|
|
12682
12451
|
Param: {
|
|
12452
|
+
Bucket: resourceId,
|
|
12683
12453
|
EnvId: envId,
|
|
12684
|
-
|
|
12454
|
+
AclTag: aclTag,
|
|
12455
|
+
Rule: rule,
|
|
12685
12456
|
},
|
|
12686
12457
|
});
|
|
12687
12458
|
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12688
|
-
function getRowPermission(policy) {
|
|
12689
|
-
return {
|
|
12690
|
-
READONLY: [
|
|
12691
|
-
{ Key: "all", Value: "r" },
|
|
12692
|
-
{ Key: "me", Value: "rw" },
|
|
12693
|
-
],
|
|
12694
|
-
PRIVATE: [{ Key: "me", Value: "rw" }],
|
|
12695
|
-
ADMINWRITE: [{ Key: "all", Value: "r" }],
|
|
12696
|
-
ADMINONLY: [],
|
|
12697
|
-
}[policy];
|
|
12698
|
-
}
|
|
12699
12459
|
}
|
|
12700
12460
|
else {
|
|
12701
|
-
|
|
12702
|
-
|
|
12703
|
-
|
|
12704
|
-
|
|
12705
|
-
|
|
12706
|
-
|
|
12707
|
-
text: JSON.stringify({
|
|
12708
|
-
success: true,
|
|
12709
|
-
requestId: result.RequestId,
|
|
12710
|
-
raw: result,
|
|
12711
|
-
message: "安全规则写入成功",
|
|
12712
|
-
}, null, 2),
|
|
12461
|
+
result = await cloudbase.commonService().call({
|
|
12462
|
+
Action: "ModifyStorageSafeRule",
|
|
12463
|
+
Param: {
|
|
12464
|
+
Bucket: resourceId,
|
|
12465
|
+
EnvId: envId,
|
|
12466
|
+
AclTag: aclTag,
|
|
12713
12467
|
},
|
|
12714
|
-
|
|
12715
|
-
|
|
12468
|
+
});
|
|
12469
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12470
|
+
}
|
|
12716
12471
|
}
|
|
12717
|
-
|
|
12718
|
-
|
|
12719
|
-
|
|
12720
|
-
|
|
12721
|
-
|
|
12722
|
-
|
|
12723
|
-
|
|
12724
|
-
|
|
12725
|
-
|
|
12726
|
-
|
|
12727
|
-
|
|
12728
|
-
|
|
12729
|
-
|
|
12472
|
+
else if (resourceType === "sqlDatabase") {
|
|
12473
|
+
if (aclTag === "CUSTOM") {
|
|
12474
|
+
throw new Error("SQL 数据库不支持自定义安全规则(CUSTOM)");
|
|
12475
|
+
}
|
|
12476
|
+
const schema = envId;
|
|
12477
|
+
const tableName = resourceId;
|
|
12478
|
+
const instanceId = "default";
|
|
12479
|
+
const resource = `${instanceId}#${schema}#${tableName}`;
|
|
12480
|
+
const resourceType = "table";
|
|
12481
|
+
const effect = "allow";
|
|
12482
|
+
const policyList = [
|
|
12483
|
+
"allUser",
|
|
12484
|
+
"anonymousUser",
|
|
12485
|
+
"externalUser",
|
|
12486
|
+
"internalUser",
|
|
12487
|
+
].map((roleIdentity) => ({
|
|
12488
|
+
RoleIdentity: roleIdentity,
|
|
12489
|
+
ResourceType: resourceType,
|
|
12490
|
+
ResourceId: resource,
|
|
12491
|
+
RowPermission: [],
|
|
12492
|
+
Effect: effect,
|
|
12493
|
+
}));
|
|
12494
|
+
policyList[0].RowPermission = getRowPermission(aclTag);
|
|
12495
|
+
result = await cloudbase.commonService("lowcode").call({
|
|
12496
|
+
Action: "BatchCreateResourcePolicy",
|
|
12497
|
+
Param: {
|
|
12498
|
+
EnvId: envId,
|
|
12499
|
+
PolicyList: policyList,
|
|
12500
|
+
},
|
|
12501
|
+
});
|
|
12502
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12503
|
+
function getRowPermission(policy) {
|
|
12504
|
+
return {
|
|
12505
|
+
READONLY: [
|
|
12506
|
+
{ Key: "all", Value: "r" },
|
|
12507
|
+
{ Key: "me", Value: "rw" },
|
|
12508
|
+
],
|
|
12509
|
+
PRIVATE: [{ Key: "me", Value: "rw" }],
|
|
12510
|
+
ADMINWRITE: [{ Key: "all", Value: "r" }],
|
|
12511
|
+
ADMINONLY: [],
|
|
12512
|
+
}[policy];
|
|
12513
|
+
}
|
|
12514
|
+
}
|
|
12515
|
+
else {
|
|
12516
|
+
throw new Error(`不支持的资源类型: ${resourceType}`);
|
|
12730
12517
|
}
|
|
12518
|
+
return {
|
|
12519
|
+
content: [
|
|
12520
|
+
{
|
|
12521
|
+
type: "text",
|
|
12522
|
+
text: JSON.stringify({
|
|
12523
|
+
success: true,
|
|
12524
|
+
requestId: result.RequestId,
|
|
12525
|
+
raw: result,
|
|
12526
|
+
message: "安全规则写入成功",
|
|
12527
|
+
}, null, 2),
|
|
12528
|
+
},
|
|
12529
|
+
],
|
|
12530
|
+
};
|
|
12731
12531
|
});
|
|
12732
12532
|
}
|
|
12733
12533
|
|
|
@@ -13410,64 +13210,44 @@ function registerDownloadTools(server) {
|
|
|
13410
13210
|
category: "download"
|
|
13411
13211
|
}
|
|
13412
13212
|
}, async ({ url, relativePath }) => {
|
|
13413
|
-
|
|
13414
|
-
// 验证相对路径安全性
|
|
13415
|
-
if (!isPathSafe(relativePath)) {
|
|
13416
|
-
return {
|
|
13417
|
-
content: [
|
|
13418
|
-
{
|
|
13419
|
-
type: "text",
|
|
13420
|
-
text: JSON.stringify({
|
|
13421
|
-
success: false,
|
|
13422
|
-
error: "不安全的相对路径",
|
|
13423
|
-
message: "相对路径包含路径遍历操作(../)或绝对路径,出于安全考虑已拒绝",
|
|
13424
|
-
suggestion: "请使用项目根目录下的相对路径,例如:'assets/images/logo.png'"
|
|
13425
|
-
}, null, 2)
|
|
13426
|
-
}
|
|
13427
|
-
]
|
|
13428
|
-
};
|
|
13429
|
-
}
|
|
13430
|
-
// 计算最终下载路径
|
|
13431
|
-
const targetPath = calculateDownloadPath(relativePath);
|
|
13432
|
-
const projectRoot = getProjectRoot();
|
|
13433
|
-
console.log(`📁 项目根目录: ${projectRoot}`);
|
|
13434
|
-
console.log(`📁 相对路径: ${relativePath}`);
|
|
13435
|
-
console.log(`📁 最终路径: ${targetPath}`);
|
|
13436
|
-
// 下载文件到指定路径
|
|
13437
|
-
const result = await downloadFileToPath(url, targetPath);
|
|
13438
|
-
return {
|
|
13439
|
-
content: [
|
|
13440
|
-
{
|
|
13441
|
-
type: "text",
|
|
13442
|
-
text: JSON.stringify({
|
|
13443
|
-
success: true,
|
|
13444
|
-
filePath: result.filePath,
|
|
13445
|
-
relativePath: relativePath,
|
|
13446
|
-
contentType: result.contentType,
|
|
13447
|
-
fileSize: result.fileSize,
|
|
13448
|
-
projectRoot: projectRoot,
|
|
13449
|
-
message: "文件下载成功到指定路径",
|
|
13450
|
-
note: `文件已保存到项目目录: ${relativePath}`
|
|
13451
|
-
}, null, 2)
|
|
13452
|
-
}
|
|
13453
|
-
]
|
|
13454
|
-
};
|
|
13455
|
-
}
|
|
13456
|
-
catch (error) {
|
|
13213
|
+
if (!isPathSafe(relativePath)) {
|
|
13457
13214
|
return {
|
|
13458
13215
|
content: [
|
|
13459
13216
|
{
|
|
13460
13217
|
type: "text",
|
|
13461
13218
|
text: JSON.stringify({
|
|
13462
13219
|
success: false,
|
|
13463
|
-
error:
|
|
13464
|
-
message: "
|
|
13465
|
-
suggestion: "
|
|
13220
|
+
error: "不安全的相对路径",
|
|
13221
|
+
message: "相对路径包含路径遍历操作(../)或绝对路径,出于安全考虑已拒绝",
|
|
13222
|
+
suggestion: "请使用项目根目录下的相对路径,例如:'assets/images/logo.png'"
|
|
13466
13223
|
}, null, 2)
|
|
13467
13224
|
}
|
|
13468
13225
|
]
|
|
13469
13226
|
};
|
|
13470
13227
|
}
|
|
13228
|
+
const targetPath = calculateDownloadPath(relativePath);
|
|
13229
|
+
const projectRoot = getProjectRoot();
|
|
13230
|
+
console.log(`📁 项目根目录: ${projectRoot}`);
|
|
13231
|
+
console.log(`📁 相对路径: ${relativePath}`);
|
|
13232
|
+
console.log(`📁 最终路径: ${targetPath}`);
|
|
13233
|
+
const result = await downloadFileToPath(url, targetPath);
|
|
13234
|
+
return {
|
|
13235
|
+
content: [
|
|
13236
|
+
{
|
|
13237
|
+
type: "text",
|
|
13238
|
+
text: JSON.stringify({
|
|
13239
|
+
success: true,
|
|
13240
|
+
filePath: result.filePath,
|
|
13241
|
+
relativePath: relativePath,
|
|
13242
|
+
contentType: result.contentType,
|
|
13243
|
+
fileSize: result.fileSize,
|
|
13244
|
+
projectRoot: projectRoot,
|
|
13245
|
+
message: "文件下载成功到指定路径",
|
|
13246
|
+
note: `文件已保存到项目目录: ${relativePath}`
|
|
13247
|
+
}, null, 2)
|
|
13248
|
+
}
|
|
13249
|
+
]
|
|
13250
|
+
};
|
|
13471
13251
|
});
|
|
13472
13252
|
}
|
|
13473
13253
|
|
|
@@ -13682,52 +13462,35 @@ function registerSQLDatabaseTools(server) {
|
|
|
13682
13462
|
category: CATEGORY,
|
|
13683
13463
|
},
|
|
13684
13464
|
}, async ({ sql }) => {
|
|
13685
|
-
|
|
13686
|
-
|
|
13687
|
-
|
|
13688
|
-
|
|
13689
|
-
|
|
13690
|
-
|
|
13691
|
-
|
|
13692
|
-
|
|
13693
|
-
|
|
13465
|
+
const cloudbase = await getManager();
|
|
13466
|
+
const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
13467
|
+
const schemaId = envId;
|
|
13468
|
+
const instanceId = "default";
|
|
13469
|
+
const result = await cloudbase.commonService("tcb", "2018-06-08").call({
|
|
13470
|
+
Action: "RunSql",
|
|
13471
|
+
Param: {
|
|
13472
|
+
EnvId: envId,
|
|
13473
|
+
Sql: sql,
|
|
13474
|
+
DbInstance: {
|
|
13694
13475
|
EnvId: envId,
|
|
13695
|
-
|
|
13696
|
-
|
|
13697
|
-
EnvId: envId,
|
|
13698
|
-
InstanceId: instanceId,
|
|
13699
|
-
Schema: schemaId,
|
|
13700
|
-
},
|
|
13476
|
+
InstanceId: instanceId,
|
|
13477
|
+
Schema: schemaId,
|
|
13701
13478
|
},
|
|
13702
|
-
}
|
|
13703
|
-
|
|
13704
|
-
|
|
13705
|
-
|
|
13706
|
-
|
|
13707
|
-
|
|
13708
|
-
|
|
13709
|
-
|
|
13710
|
-
|
|
13711
|
-
|
|
13712
|
-
|
|
13713
|
-
},
|
|
13714
|
-
|
|
13715
|
-
|
|
13716
|
-
}
|
|
13717
|
-
catch (error) {
|
|
13718
|
-
return {
|
|
13719
|
-
content: [
|
|
13720
|
-
{
|
|
13721
|
-
type: "text",
|
|
13722
|
-
text: JSON.stringify({
|
|
13723
|
-
success: false,
|
|
13724
|
-
error: error.message,
|
|
13725
|
-
message: "SQL query execution failed",
|
|
13726
|
-
}, null, 2),
|
|
13727
|
-
},
|
|
13728
|
-
],
|
|
13729
|
-
};
|
|
13730
|
-
}
|
|
13479
|
+
},
|
|
13480
|
+
});
|
|
13481
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
13482
|
+
return {
|
|
13483
|
+
content: [
|
|
13484
|
+
{
|
|
13485
|
+
type: "text",
|
|
13486
|
+
text: JSON.stringify({
|
|
13487
|
+
success: true,
|
|
13488
|
+
message: "SQL query executed successfully",
|
|
13489
|
+
result,
|
|
13490
|
+
}, null, 2),
|
|
13491
|
+
},
|
|
13492
|
+
],
|
|
13493
|
+
};
|
|
13731
13494
|
});
|
|
13732
13495
|
// executeWriteSQL
|
|
13733
13496
|
server.registerTool?.("executeWriteSQL", {
|
|
@@ -13746,52 +13509,35 @@ function registerSQLDatabaseTools(server) {
|
|
|
13746
13509
|
category: CATEGORY,
|
|
13747
13510
|
},
|
|
13748
13511
|
}, async ({ sql }) => {
|
|
13749
|
-
|
|
13750
|
-
|
|
13751
|
-
|
|
13752
|
-
|
|
13753
|
-
|
|
13754
|
-
|
|
13755
|
-
|
|
13756
|
-
|
|
13757
|
-
|
|
13512
|
+
const cloudbase = await getManager();
|
|
13513
|
+
const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
13514
|
+
const schemaId = envId;
|
|
13515
|
+
const instanceId = "default";
|
|
13516
|
+
const result = await cloudbase.commonService("tcb", "2018-06-08").call({
|
|
13517
|
+
Action: "RunSql",
|
|
13518
|
+
Param: {
|
|
13519
|
+
EnvId: envId,
|
|
13520
|
+
Sql: sql,
|
|
13521
|
+
DbInstance: {
|
|
13758
13522
|
EnvId: envId,
|
|
13759
|
-
|
|
13760
|
-
|
|
13761
|
-
EnvId: envId,
|
|
13762
|
-
InstanceId: instanceId,
|
|
13763
|
-
Schema: schemaId,
|
|
13764
|
-
},
|
|
13523
|
+
InstanceId: instanceId,
|
|
13524
|
+
Schema: schemaId,
|
|
13765
13525
|
},
|
|
13766
|
-
}
|
|
13767
|
-
|
|
13768
|
-
|
|
13769
|
-
|
|
13770
|
-
|
|
13771
|
-
|
|
13772
|
-
|
|
13773
|
-
|
|
13774
|
-
|
|
13775
|
-
|
|
13776
|
-
|
|
13777
|
-
},
|
|
13778
|
-
|
|
13779
|
-
|
|
13780
|
-
}
|
|
13781
|
-
catch (error) {
|
|
13782
|
-
return {
|
|
13783
|
-
content: [
|
|
13784
|
-
{
|
|
13785
|
-
type: "text",
|
|
13786
|
-
text: JSON.stringify({
|
|
13787
|
-
success: false,
|
|
13788
|
-
error: error.message,
|
|
13789
|
-
message: "SQL statement execution failed",
|
|
13790
|
-
}, null, 2),
|
|
13791
|
-
},
|
|
13792
|
-
],
|
|
13793
|
-
};
|
|
13794
|
-
}
|
|
13526
|
+
},
|
|
13527
|
+
});
|
|
13528
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
13529
|
+
return {
|
|
13530
|
+
content: [
|
|
13531
|
+
{
|
|
13532
|
+
type: "text",
|
|
13533
|
+
text: JSON.stringify({
|
|
13534
|
+
success: true,
|
|
13535
|
+
message: `SQL statement executed successfully. If you just created a table, make sure to check its security rule is set to a proper value by using \`${security_rule_js_1.WRITE_SECURITY_RULE}\` and \`${security_rule_js_1.READ_SECURITY_RULE}\` tools.`,
|
|
13536
|
+
result,
|
|
13537
|
+
}, null, 2),
|
|
13538
|
+
},
|
|
13539
|
+
],
|
|
13540
|
+
};
|
|
13795
13541
|
});
|
|
13796
13542
|
}
|
|
13797
13543
|
|