@cloudbase/manager-node 4.7.0-beta.0 → 4.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/agent/index.js +1 -142
- package/lib/cloudrun/index.js +2 -2
- package/lib/common/index.js +1 -1
- package/lib/constant.js +2 -1
- package/lib/context.js +10 -1
- package/lib/env/index.js +3 -2
- package/lib/environment.js +1 -0
- package/lib/function/index.js +130 -36
- package/lib/index.js +7 -2
- package/lib/storage/index.js +3 -2
- package/lib/utils/cloud-api-request.js +7 -2
- package/package.json +1 -1
- package/types/agent/index.d.ts +2 -36
- package/types/agent/type.d.ts +0 -354
- package/types/constant.d.ts +1 -0
- package/types/context.d.ts +7 -1
- package/types/function/index.d.ts +15 -1
- package/types/function/types.d.ts +4 -1
- package/types/index.d.ts +3 -0
- package/types/interfaces/function.interface.d.ts +2 -0
- package/.cursor/rules/cloudbase-rules.mdc +0 -119
package/lib/agent/index.js
CHANGED
|
@@ -15,18 +15,14 @@ const utils_1 = require("../utils");
|
|
|
15
15
|
const path_1 = __importDefault(require("path"));
|
|
16
16
|
/**
|
|
17
17
|
* Agent 管理类
|
|
18
|
-
* 提供新版 Agent 的完整生命周期管理功能
|
|
19
18
|
*/
|
|
20
19
|
class AgentService {
|
|
21
20
|
constructor(environment) {
|
|
22
21
|
this.environment = environment;
|
|
23
22
|
this.tcbService = new utils_1.CloudService(environment.cloudBaseContext, 'tcb', '2018-06-08');
|
|
24
|
-
this.scfService = new utils_1.CloudService(environment.cloudBaseContext, 'scf', '2018-04-16');
|
|
25
|
-
this.functionService = environment.getFunctionService();
|
|
26
|
-
this.userService = environment.getUserService();
|
|
27
23
|
}
|
|
28
24
|
/**
|
|
29
|
-
* 创建函数型 Agent
|
|
25
|
+
* 创建函数型 Agent
|
|
30
26
|
* @param {string} [cwd=process.cwd()] 工作目录
|
|
31
27
|
* @param {ICreateFunctionAgentParams} agentInfo Agent 信息
|
|
32
28
|
* @returns {Promise<{ BotId: string; RequestId: string }>} Agent 创建结果
|
|
@@ -67,145 +63,8 @@ class AgentService {
|
|
|
67
63
|
});
|
|
68
64
|
return this.tcbService.request('CreateBot', Object.assign(Object.assign({}, agentInfo), { EnvId: envConfig.EnvId, PackageName: packageName, PackageVersion: packageVersion }));
|
|
69
65
|
}
|
|
70
|
-
/**
|
|
71
|
-
* 部署新版 Agent 到 web云函数
|
|
72
|
-
* @param {ICreateAgentParams} params 创建参数
|
|
73
|
-
* @returns {Promise<IResponseInfo>} 创建结果
|
|
74
|
-
*/
|
|
75
|
-
async deployWebFn(params, isFirstDeploy = true) {
|
|
76
|
-
const envConfig = this.environment.lazyEnvironmentConfig;
|
|
77
|
-
const { name, agentId, agentPath, agentRootPath, deployConfig } = params;
|
|
78
|
-
// 构造部署参数
|
|
79
|
-
const deployAgentData = Object.assign({}, deployConfig);
|
|
80
|
-
// 上传代码包到 COS
|
|
81
|
-
const uploadRes = await this.functionService.uploadFunctionZipToCos({ func: { name: name, ignore: deployConfig.ignore }, functionPath: agentPath, functionRootPath: agentRootPath }, 'FALSE');
|
|
82
|
-
console.log('uploadRes', uploadRes);
|
|
83
|
-
const { Key } = uploadRes;
|
|
84
|
-
console.log('tempobjectkey', Key);
|
|
85
|
-
deployAgentData.code = {
|
|
86
|
-
cosBucketRegion: 'ap-shanghai',
|
|
87
|
-
tempCosObjectName: `/${Key}`
|
|
88
|
-
};
|
|
89
|
-
// 使用 zipFile 上传
|
|
90
|
-
// deployAgentData.code = await this.getCodeParams({ deployConfig, agentPath, agentRootPath })
|
|
91
|
-
try {
|
|
92
|
-
let res;
|
|
93
|
-
if (isFirstDeploy) {
|
|
94
|
-
// 调用创建接口 TODO: 临时屏蔽 resourceList
|
|
95
|
-
res = await this.tcbService.request('CreateAgent', (0, utils_1.upperCaseObjKey)({
|
|
96
|
-
envId: envConfig.EnvId,
|
|
97
|
-
// agentId,
|
|
98
|
-
name,
|
|
99
|
-
runtimeConfig: Object.assign(Object.assign({}, deployAgentData), { ignore: undefined, resources: undefined, environment: undefined, functionName: undefined })
|
|
100
|
-
}));
|
|
101
|
-
console.log('CreateAgent res', res);
|
|
102
|
-
// 等待函数状态正常
|
|
103
|
-
await this.functionService.waitFunctionActive(res.AgentId);
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
// 调用函数代码更新接口
|
|
107
|
-
res = await this.scfService.request('UpdateFunctionCode', {
|
|
108
|
-
FunctionName: agentId,
|
|
109
|
-
Namespace: envConfig.EnvId,
|
|
110
|
-
InstallDependency: 'FALSE',
|
|
111
|
-
Code: deployAgentData.code
|
|
112
|
-
});
|
|
113
|
-
console.log('UpdateFunctionCode res', res);
|
|
114
|
-
// 等待函数状态正常
|
|
115
|
-
await this.functionService.waitFunctionActive(agentId);
|
|
116
|
-
}
|
|
117
|
-
return res;
|
|
118
|
-
}
|
|
119
|
-
catch (error) {
|
|
120
|
-
throw new Error(`${isFirstDeploy ? '创建' : '更新'} Agent 失败: ${error.message}`);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* 获取 Agent 列表
|
|
125
|
-
* @param {IListAgentsParams} [params] 查询参数
|
|
126
|
-
* @returns {Promise<IListAgentsResponse>} Agent 列表
|
|
127
|
-
*/
|
|
128
|
-
async list(params) {
|
|
129
|
-
const envConfig = this.environment.lazyEnvironmentConfig;
|
|
130
|
-
const { limit = 20, offset = 0, agentId } = params || {};
|
|
131
|
-
// 转化为 pageSize 和 pageNum
|
|
132
|
-
const pageSize = limit;
|
|
133
|
-
const pageNumber = Math.floor(offset / limit) + 1;
|
|
134
|
-
try {
|
|
135
|
-
const params = {
|
|
136
|
-
EnvId: envConfig.EnvId,
|
|
137
|
-
};
|
|
138
|
-
if (agentId) {
|
|
139
|
-
params.AgentId = agentId;
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
params.PageSize = pageSize;
|
|
143
|
-
params.PageNumber = pageNumber;
|
|
144
|
-
}
|
|
145
|
-
const res = await this.tcbService.request('DescribeAgentList', params);
|
|
146
|
-
console.log('DescribeAgentList res', JSON.stringify(res, null, 2));
|
|
147
|
-
const transformAggentList = await Promise.all(res.AgentList.map(async (item) => {
|
|
148
|
-
const fnDetail = await this.functionService.getFunctionDetail(item.AgentId);
|
|
149
|
-
return Object.assign(Object.assign({}, item), { RuntimeConfig: Object.assign(Object.assign({}, item.RuntimeConfig), { Runtime: fnDetail.Runtime, MemorySize: fnDetail.MemorySize, Timeout: fnDetail.Timeout }) });
|
|
150
|
-
}));
|
|
151
|
-
return Object.assign(Object.assign({}, res), { AgentList: transformAggentList });
|
|
152
|
-
}
|
|
153
|
-
catch (error) {
|
|
154
|
-
throw new Error(`获取 Agent 列表失败: ${error.message}`);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* 获取 Agent 详情
|
|
159
|
-
* @param {object} params 查询参数
|
|
160
|
-
* @param {string} params.agentId Agent ID
|
|
161
|
-
* @returns {Promise<IAgentDetailResponse>} Agent 详情
|
|
162
|
-
*/
|
|
163
|
-
async getAgentInfo(params) {
|
|
164
|
-
const listRes = await this.list({ agentId: params.agentId });
|
|
165
|
-
if (listRes.Total > 0) {
|
|
166
|
-
return listRes.AgentList[0];
|
|
167
|
-
}
|
|
168
|
-
else {
|
|
169
|
-
return null;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* 删除 Agent
|
|
174
|
-
* @param {IDeleteAgentParams} params 删除参数
|
|
175
|
-
* @returns {Promise<IResponseInfo>} 删除结果
|
|
176
|
-
*/
|
|
177
|
-
async delete(params) {
|
|
178
|
-
const envConfig = this.environment.lazyEnvironmentConfig;
|
|
179
|
-
const { agentId } = params;
|
|
180
|
-
try {
|
|
181
|
-
// 1. 删除 Agent 实体
|
|
182
|
-
const res = await this.tcbService.request('DeleteAgent', {
|
|
183
|
-
EnvId: envConfig.EnvId,
|
|
184
|
-
AgentId: agentId
|
|
185
|
-
});
|
|
186
|
-
// 2. 删除 agentId 对应的函数
|
|
187
|
-
const deleteFunctionRes = await this.functionService.deleteFunction({ name: agentId });
|
|
188
|
-
console.log('deleteFunctionRes', deleteFunctionRes);
|
|
189
|
-
return res;
|
|
190
|
-
}
|
|
191
|
-
catch (error) {
|
|
192
|
-
throw new Error(`删除 Agent 失败: ${error.message}`);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
66
|
}
|
|
196
67
|
exports.AgentService = AgentService;
|
|
197
68
|
__decorate([
|
|
198
69
|
(0, utils_1.preLazy)()
|
|
199
70
|
], AgentService.prototype, "createFunctionAgent", null);
|
|
200
|
-
__decorate([
|
|
201
|
-
(0, utils_1.preLazy)()
|
|
202
|
-
], AgentService.prototype, "deployWebFn", null);
|
|
203
|
-
__decorate([
|
|
204
|
-
(0, utils_1.preLazy)()
|
|
205
|
-
], AgentService.prototype, "list", null);
|
|
206
|
-
__decorate([
|
|
207
|
-
(0, utils_1.preLazy)()
|
|
208
|
-
], AgentService.prototype, "getAgentInfo", null);
|
|
209
|
-
__decorate([
|
|
210
|
-
(0, utils_1.preLazy)()
|
|
211
|
-
], AgentService.prototype, "delete", null);
|
package/lib/cloudrun/index.js
CHANGED
|
@@ -196,7 +196,7 @@ class CloudRunService {
|
|
|
196
196
|
if (await this._checkFunctionExist(serverName)) {
|
|
197
197
|
// 更新
|
|
198
198
|
const serverDetail = await this.detail({ serverName });
|
|
199
|
-
const _serverConfig = Object.assign(Object.assign({}, serverConfig), ((serverDetail === null || serverDetail === void 0 ? void 0 : serverDetail.ServerConfig.Tag) === 'function:' ? { Port: 3000 } : {}) // 函数型不能指定端口,需要固定为3000
|
|
199
|
+
const _serverConfig = Object.assign(Object.assign(Object.assign({}, serverConfig), { OpenAccessTypes: ['OA', 'PUBLIC', 'MINIAPP'] }), ((serverDetail === null || serverDetail === void 0 ? void 0 : serverDetail.ServerConfig.Tag) === 'function:' ? { Port: 3000 } : {}) // 函数型不能指定端口,需要固定为3000
|
|
200
200
|
);
|
|
201
201
|
if ((serverDetail === null || serverDetail === void 0 ? void 0 : serverDetail.ServerConfig.Tag) === 'function:') {
|
|
202
202
|
deployInfo.BuildPacks = {
|
|
@@ -231,7 +231,7 @@ class CloudRunService {
|
|
|
231
231
|
RepoLanguage: 'Node.js'
|
|
232
232
|
};
|
|
233
233
|
}
|
|
234
|
-
const _serverConfig = Object.assign(Object.assign(Object.assign({ OpenAccessTypes: ['OA', 'PUBLIC'],
|
|
234
|
+
const _serverConfig = Object.assign(Object.assign(Object.assign({ OpenAccessTypes: ['OA', 'PUBLIC', 'MINIAPP'],
|
|
235
235
|
// Cpu: 0,
|
|
236
236
|
// Mem: 0,
|
|
237
237
|
MinNum: 0,
|
package/lib/common/index.js
CHANGED
package/lib/constant.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// static credentail = 'credential'
|
|
5
5
|
// }
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.COS_SDK_KEEPALIVE = exports.COS_SDK_PROTOCOL = exports.USE_INTERNAL_ENDPOINT = exports.SCF_STATUS = exports.ROLE_NAME = exports.PUBLIC_RSA_KEY = exports.ERROR = exports.SERVICE_TYPE = exports.ENDPOINT = exports.RUN_ENV = exports.SDK_VERSION = exports.ENV_NAME = void 0;
|
|
7
|
+
exports.COS_SDK_KEEPALIVE = exports.COS_SDK_PROTOCOL = exports.INTERNAL_ENDPOINT_REGION = exports.USE_INTERNAL_ENDPOINT = exports.SCF_STATUS = exports.ROLE_NAME = exports.PUBLIC_RSA_KEY = exports.ERROR = exports.SERVICE_TYPE = exports.ENDPOINT = exports.RUN_ENV = exports.SDK_VERSION = exports.ENV_NAME = void 0;
|
|
8
8
|
exports.ENV_NAME = {
|
|
9
9
|
ENV_SECRETID: 'TENCENTCLOUD_SECRETID',
|
|
10
10
|
ENV_SECRETKEY: 'TENCENTCLOUD_SECRETKEY',
|
|
@@ -56,5 +56,6 @@ exports.SCF_STATUS = {
|
|
|
56
56
|
};
|
|
57
57
|
// 是否使用内网域名
|
|
58
58
|
exports.USE_INTERNAL_ENDPOINT = "USE_INTERNAL_ENDPOINT" in process.env;
|
|
59
|
+
exports.INTERNAL_ENDPOINT_REGION = process.env.INTERNAL_ENDPOINT_REGION;
|
|
59
60
|
exports.COS_SDK_PROTOCOL = process.env.COS_SDK_PROTOCOL;
|
|
60
61
|
exports.COS_SDK_KEEPALIVE = process.env.COS_SDK_KEEPALIVE;
|
package/lib/context.js
CHANGED
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CloudBaseContext = void 0;
|
|
4
|
+
const constant_1 = require("./constant");
|
|
4
5
|
class CloudBaseContext {
|
|
5
|
-
constructor({ secretId = '', secretKey = '', token = '', proxy = '', region = '', envType = '' }) {
|
|
6
|
+
constructor({ secretId = '', secretKey = '', token = '', proxy = '', region = '', envType = '', useInternalEndpoint = undefined, internalEndpointRegion = undefined }) {
|
|
6
7
|
this.secretId = secretId;
|
|
7
8
|
this.secretKey = secretKey;
|
|
8
9
|
this.token = token;
|
|
9
10
|
this.proxy = proxy;
|
|
10
11
|
this.region = region;
|
|
11
12
|
this.envType = envType;
|
|
13
|
+
this.useInternalEndpoint = useInternalEndpoint;
|
|
14
|
+
this.internalEndpointRegion = internalEndpointRegion;
|
|
15
|
+
}
|
|
16
|
+
isInternalEndpoint() {
|
|
17
|
+
return this.useInternalEndpoint !== undefined ? this.useInternalEndpoint : constant_1.USE_INTERNAL_ENDPOINT;
|
|
18
|
+
}
|
|
19
|
+
getInternalEndpointRegion() {
|
|
20
|
+
return this.internalEndpointRegion || constant_1.INTERNAL_ENDPOINT_REGION;
|
|
12
21
|
}
|
|
13
22
|
}
|
|
14
23
|
exports.CloudBaseContext = CloudBaseContext;
|
package/lib/env/index.js
CHANGED
|
@@ -280,19 +280,20 @@ class EnvService {
|
|
|
280
280
|
});
|
|
281
281
|
}
|
|
282
282
|
getCos() {
|
|
283
|
+
const internalEndpoint = this.environment.cloudBaseContext.isInternalEndpoint();
|
|
283
284
|
const { secretId, secretKey, token } = this.environment.getAuthConfig();
|
|
284
285
|
const cosConfig = {
|
|
285
286
|
SecretId: secretId,
|
|
286
287
|
SecretKey: secretKey,
|
|
287
288
|
SecurityToken: token,
|
|
288
|
-
Domain:
|
|
289
|
+
Domain: internalEndpoint ? "{Bucket}.cos-internal.{Region}.tencentcos.cn" /* COS_ENDPOINT.INTERNAL */ : "{Bucket}.cos.{Region}.tencentcos.cn" /* COS_ENDPOINT.PUBLIC */,
|
|
289
290
|
};
|
|
290
291
|
if (constant_1.COS_SDK_PROTOCOL) {
|
|
291
292
|
cosConfig.Protocol = (constant_1.COS_SDK_PROTOCOL.endsWith(':')
|
|
292
293
|
? constant_1.COS_SDK_PROTOCOL.toLowerCase()
|
|
293
294
|
: constant_1.COS_SDK_PROTOCOL.toLowerCase() + ':');
|
|
294
295
|
}
|
|
295
|
-
if (
|
|
296
|
+
if (internalEndpoint) {
|
|
296
297
|
cosConfig.Protocol = 'http:';
|
|
297
298
|
}
|
|
298
299
|
return new cos_nodejs_sdk_v5_1.default(cosConfig);
|
package/lib/environment.js
CHANGED
|
@@ -33,6 +33,7 @@ class Environment {
|
|
|
33
33
|
this.hostingService = new hosting_1.HostingService(this);
|
|
34
34
|
this.thirdService = new third_1.ThirdService(this);
|
|
35
35
|
this.accessService = new access_1.AccessService(this);
|
|
36
|
+
this.userService = new user_1.UserService(this);
|
|
36
37
|
this.cloudBaseRunService = new cloudBaseRun_1.CloudBaseRunService(this);
|
|
37
38
|
}
|
|
38
39
|
async lazyInit() {
|
package/lib/function/index.js
CHANGED
|
@@ -13,11 +13,11 @@ exports.FunctionService = void 0;
|
|
|
13
13
|
const fs_1 = __importDefault(require("fs"));
|
|
14
14
|
const path_1 = __importDefault(require("path"));
|
|
15
15
|
const lodash_1 = __importDefault(require("lodash"));
|
|
16
|
+
const cos_nodejs_sdk_v5_1 = __importDefault(require("cos-nodejs-sdk-v5"));
|
|
16
17
|
const packer_1 = require("./packer");
|
|
17
18
|
const error_1 = require("../error");
|
|
18
19
|
const utils_1 = require("../utils");
|
|
19
20
|
const constant_1 = require("../constant");
|
|
20
|
-
const cos_nodejs_sdk_v5_1 = __importDefault(require("cos-nodejs-sdk-v5"));
|
|
21
21
|
// 是否为 Node 函数
|
|
22
22
|
function isNodeFunction(runtime) {
|
|
23
23
|
// 不严格限制
|
|
@@ -78,6 +78,14 @@ function configToParams(options) {
|
|
|
78
78
|
}));
|
|
79
79
|
params.Layers = transformLayers;
|
|
80
80
|
}
|
|
81
|
+
// HTTP 云函数类型
|
|
82
|
+
if ((func === null || func === void 0 ? void 0 : func.type) === 'HTTP') {
|
|
83
|
+
params.Type = 'HTTP';
|
|
84
|
+
}
|
|
85
|
+
// 云函数描述
|
|
86
|
+
if (func === null || func === void 0 ? void 0 : func.description) {
|
|
87
|
+
params.Description = func.description;
|
|
88
|
+
}
|
|
81
89
|
return params;
|
|
82
90
|
}
|
|
83
91
|
class FunctionService {
|
|
@@ -95,12 +103,12 @@ class FunctionService {
|
|
|
95
103
|
* @memberof FunctionService
|
|
96
104
|
*/
|
|
97
105
|
async updateFunctionIncrementalCode(funcParam) {
|
|
98
|
-
const {
|
|
106
|
+
const { env } = this.getFunctionConfig();
|
|
99
107
|
const { functionRootPath, func, deleteFiles, addFiles } = funcParam;
|
|
100
108
|
const { name, runtime } = func;
|
|
101
109
|
const params = {
|
|
102
110
|
FunctionName: name,
|
|
103
|
-
|
|
111
|
+
EnvId: env
|
|
104
112
|
};
|
|
105
113
|
let packer;
|
|
106
114
|
let base64;
|
|
@@ -124,7 +132,7 @@ class FunctionService {
|
|
|
124
132
|
}
|
|
125
133
|
params.AddFiles = base64;
|
|
126
134
|
}
|
|
127
|
-
return this.
|
|
135
|
+
return this.tcbService.request('UpdateFunctionIncrementalCode', params);
|
|
128
136
|
}
|
|
129
137
|
/**
|
|
130
138
|
* 创建云函数
|
|
@@ -132,14 +140,14 @@ class FunctionService {
|
|
|
132
140
|
* @returns {(Promise<IResponseInfo | ICreateFunctionRes>)}
|
|
133
141
|
*/
|
|
134
142
|
async createFunction(funcParam) {
|
|
135
|
-
const {
|
|
136
|
-
const { func, functionRootPath, force = false, base64Code, codeSecret, functionPath } = funcParam;
|
|
143
|
+
const { env } = this.getFunctionConfig();
|
|
144
|
+
const { func, functionRootPath, force = false, base64Code, codeSecret, functionPath, deployMode } = funcParam;
|
|
137
145
|
const funcName = func.name;
|
|
138
146
|
const params = configToParams({
|
|
139
147
|
func,
|
|
140
148
|
codeSecret,
|
|
141
149
|
baseParams: {
|
|
142
|
-
|
|
150
|
+
EnvId: env,
|
|
143
151
|
Role: 'TCB_QcsRole',
|
|
144
152
|
Stamp: 'MINI_QCBASE'
|
|
145
153
|
}
|
|
@@ -148,14 +156,15 @@ class FunctionService {
|
|
|
148
156
|
func,
|
|
149
157
|
base64Code,
|
|
150
158
|
functionPath,
|
|
151
|
-
functionRootPath
|
|
159
|
+
functionRootPath,
|
|
160
|
+
deployMode
|
|
152
161
|
}, params.InstallDependency);
|
|
153
162
|
const { TopicId, LogsetId } = this.getClsServiceConfig();
|
|
154
163
|
params.ClsTopicId = TopicId;
|
|
155
164
|
params.ClsLogsetId = LogsetId;
|
|
156
165
|
try {
|
|
157
166
|
// 创建云函数
|
|
158
|
-
const res = await this.
|
|
167
|
+
const res = await this.tcbService.request('CreateFunction', params);
|
|
159
168
|
// 等待函数状态正常
|
|
160
169
|
await this.waitFunctionActive(funcName, codeSecret);
|
|
161
170
|
// 创建函数触发器、失败自动重试
|
|
@@ -224,9 +233,9 @@ class FunctionService {
|
|
|
224
233
|
*/
|
|
225
234
|
async getFunctionList(limit = 20, offset = 0) {
|
|
226
235
|
// 获取Function 环境配置
|
|
227
|
-
const {
|
|
228
|
-
const res = await this.
|
|
229
|
-
|
|
236
|
+
const { env } = this.getFunctionConfig();
|
|
237
|
+
const res = await this.tcbService.request('ListFunctions', {
|
|
238
|
+
EnvId: env,
|
|
230
239
|
Limit: limit,
|
|
231
240
|
Offset: offset
|
|
232
241
|
});
|
|
@@ -357,16 +366,17 @@ class FunctionService {
|
|
|
357
366
|
* @returns {Promise<Record<string, string>>}
|
|
358
367
|
*/
|
|
359
368
|
async getFunctionDetail(name, codeSecret) {
|
|
360
|
-
const {
|
|
369
|
+
const { env } = this.getFunctionConfig();
|
|
361
370
|
const params = {
|
|
362
371
|
FunctionName: name,
|
|
363
|
-
|
|
364
|
-
ShowCode: 'TRUE'
|
|
372
|
+
EnvId: env,
|
|
373
|
+
ShowCode: 'TRUE',
|
|
374
|
+
Namespace: env
|
|
365
375
|
};
|
|
366
376
|
if (codeSecret) {
|
|
367
377
|
params.CodeSecret = codeSecret;
|
|
368
378
|
}
|
|
369
|
-
const data = await this.
|
|
379
|
+
const data = await this.tcbService.request('GetFunction', params);
|
|
370
380
|
// 解析 VPC 配置
|
|
371
381
|
const { VpcId = '', SubnetId = '' } = data.VpcConfig || {};
|
|
372
382
|
if (VpcId && SubnetId) {
|
|
@@ -556,6 +566,9 @@ class FunctionService {
|
|
|
556
566
|
Namespace: namespace,
|
|
557
567
|
L5Enable: l5Enable
|
|
558
568
|
};
|
|
569
|
+
if (func === null || func === void 0 ? void 0 : func.description) {
|
|
570
|
+
params.Description = func.description;
|
|
571
|
+
}
|
|
559
572
|
// 修复参数存在 undefined 字段时,会出现鉴权失败的情况
|
|
560
573
|
// Environment 为覆盖式修改,不保留已有字段
|
|
561
574
|
envVariables.length && (params.Environment = { Variables: envVariables });
|
|
@@ -612,9 +625,9 @@ class FunctionService {
|
|
|
612
625
|
* @memberof FunctionService
|
|
613
626
|
*/
|
|
614
627
|
async updateFunctionCode(funcParam) {
|
|
615
|
-
const { func, functionRootPath, base64Code, codeSecret, functionPath } = funcParam;
|
|
628
|
+
const { func, functionRootPath, base64Code, codeSecret, functionPath, deployMode } = funcParam;
|
|
616
629
|
const funcName = func.name;
|
|
617
|
-
const {
|
|
630
|
+
const { env } = this.getFunctionConfig();
|
|
618
631
|
let installDependency;
|
|
619
632
|
// Node 函数默认安装依赖
|
|
620
633
|
installDependency = isNodeFunction(func.runtime) ? 'TRUE' : 'FALSE';
|
|
@@ -626,9 +639,16 @@ class FunctionService {
|
|
|
626
639
|
func,
|
|
627
640
|
functionPath,
|
|
628
641
|
functionRootPath,
|
|
629
|
-
base64Code
|
|
642
|
+
base64Code,
|
|
643
|
+
deployMode
|
|
630
644
|
}, installDependency);
|
|
631
|
-
const params =
|
|
645
|
+
const params = {
|
|
646
|
+
FunctionName: funcName,
|
|
647
|
+
EnvId: env,
|
|
648
|
+
Handler: func.handler || 'index.main',
|
|
649
|
+
InstallDependency: installDependency,
|
|
650
|
+
Code: codeParams
|
|
651
|
+
};
|
|
632
652
|
if (codeSecret) {
|
|
633
653
|
params.CodeSecret = codeSecret;
|
|
634
654
|
}
|
|
@@ -636,7 +656,7 @@ class FunctionService {
|
|
|
636
656
|
// 等待函数状态正常
|
|
637
657
|
await this.waitFunctionActive(funcName, codeSecret);
|
|
638
658
|
// 更新云函数代码
|
|
639
|
-
const res = await this.
|
|
659
|
+
const res = await this.tcbService.request('UpdateFunctionCode', params);
|
|
640
660
|
if (installDependency && func.isWaitInstall === true) {
|
|
641
661
|
await this.waitFunctionActive(funcName, codeSecret);
|
|
642
662
|
}
|
|
@@ -1145,14 +1165,17 @@ class FunctionService {
|
|
|
1145
1165
|
Namespace: namespace
|
|
1146
1166
|
});
|
|
1147
1167
|
}
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1168
|
+
/**
|
|
1169
|
+
* 通过scf COS 上传方式(通过 GetTempCosInfo + COS SDK 上传)
|
|
1170
|
+
* 返回 TempCosObjectName 用于创建/更新函数
|
|
1171
|
+
*/
|
|
1172
|
+
async uploadFunctionZipToCosLegacy(options, installDependency) {
|
|
1173
|
+
const { func, functionPath, functionRootPath } = options;
|
|
1174
|
+
const { env } = this.getFunctionConfig();
|
|
1151
1175
|
const { CloudAppId } = await this.userService.getTcbAccountInfo();
|
|
1152
1176
|
const objectPath = `${CloudAppId}/${env}/${func.name}.zip`;
|
|
1153
|
-
console.log('objectPath', objectPath);
|
|
1154
1177
|
// 1. 生成存放函数包的临时 Cos 目录
|
|
1155
|
-
const { Date, Sign
|
|
1178
|
+
const { Date: cosDate, Sign } = await this.scfService.request('GetTempCosInfo', {
|
|
1156
1179
|
ObjectPath: `${objectPath}`
|
|
1157
1180
|
});
|
|
1158
1181
|
// 2. 本地压缩
|
|
@@ -1170,7 +1193,7 @@ class FunctionService {
|
|
|
1170
1193
|
});
|
|
1171
1194
|
const zipFilePath = await packer.compressFiles();
|
|
1172
1195
|
// 3. 初始化 cos 并上传
|
|
1173
|
-
const tempCosObjectName = `/${
|
|
1196
|
+
const tempCosObjectName = `/${cosDate}/${objectPath}`;
|
|
1174
1197
|
const TEMP_COS_APPID = '1253665819';
|
|
1175
1198
|
const uploadParams = {
|
|
1176
1199
|
Bucket: `shtempcos-${TEMP_COS_APPID}`,
|
|
@@ -1185,7 +1208,9 @@ class FunctionService {
|
|
|
1185
1208
|
}
|
|
1186
1209
|
});
|
|
1187
1210
|
return new Promise((resolve, reject) => {
|
|
1188
|
-
cos.sliceUploadFile(uploadParams, (err, data) => {
|
|
1211
|
+
cos.sliceUploadFile(uploadParams, async (err, data) => {
|
|
1212
|
+
// 清理临时文件
|
|
1213
|
+
await packer.clean();
|
|
1189
1214
|
if (err) {
|
|
1190
1215
|
reject(err);
|
|
1191
1216
|
}
|
|
@@ -1195,6 +1220,59 @@ class FunctionService {
|
|
|
1195
1220
|
});
|
|
1196
1221
|
});
|
|
1197
1222
|
}
|
|
1223
|
+
/**
|
|
1224
|
+
* 新的 COS 上传方式(通过 DescribeBuildServiceCosInfo + PUT 上传)
|
|
1225
|
+
* 返回 CosTimestamp 用于创建/更新函数
|
|
1226
|
+
*/
|
|
1227
|
+
async uploadFunctionZipToCos(options, installDependency) {
|
|
1228
|
+
const { func, functionPath, functionRootPath } = options;
|
|
1229
|
+
const { env } = this.getFunctionConfig();
|
|
1230
|
+
// 1. 生成存放函数包的临时 Cos 目录
|
|
1231
|
+
const { UploadUrl, UnixTimestamp, UploadHeaders } = await this.tcbService.request('DescribeBuildServiceCosInfo', {
|
|
1232
|
+
EnvId: env,
|
|
1233
|
+
ServiceName: func.name,
|
|
1234
|
+
Business: 'scf',
|
|
1235
|
+
Suffix: '.zip'
|
|
1236
|
+
});
|
|
1237
|
+
// 2. 本地压缩
|
|
1238
|
+
const codeType = packer_1.CodeType.File;
|
|
1239
|
+
// 云端安装依赖,自动忽略 node_modules 目录
|
|
1240
|
+
const ignore = installDependency === 'TRUE'
|
|
1241
|
+
? ['node_modules/**/*', 'node_modules', ...(func.ignore || [])]
|
|
1242
|
+
: [...(func.ignore || [])];
|
|
1243
|
+
const packer = new packer_1.FunctionPacker({
|
|
1244
|
+
ignore,
|
|
1245
|
+
codeType,
|
|
1246
|
+
functionPath,
|
|
1247
|
+
name: func.name,
|
|
1248
|
+
root: functionRootPath
|
|
1249
|
+
});
|
|
1250
|
+
const zipFilePath = await packer.compressFiles();
|
|
1251
|
+
// 3. 通过 UploadUrl 直接上传
|
|
1252
|
+
const fileBuffer = fs_1.default.readFileSync(zipFilePath);
|
|
1253
|
+
// 构建请求头
|
|
1254
|
+
const headers = {
|
|
1255
|
+
'Content-Type': 'application/zip'
|
|
1256
|
+
};
|
|
1257
|
+
if (UploadHeaders && UploadHeaders.length > 0) {
|
|
1258
|
+
UploadHeaders.forEach(item => {
|
|
1259
|
+
headers[item.Key] = item.Value;
|
|
1260
|
+
});
|
|
1261
|
+
}
|
|
1262
|
+
const response = await fetch(UploadUrl, {
|
|
1263
|
+
method: 'PUT',
|
|
1264
|
+
body: fileBuffer,
|
|
1265
|
+
headers
|
|
1266
|
+
});
|
|
1267
|
+
if (!response.ok) {
|
|
1268
|
+
throw new error_1.CloudBaseError(`上传失败: ${response.status} ${response.statusText}`);
|
|
1269
|
+
}
|
|
1270
|
+
// 清理临时文件
|
|
1271
|
+
await packer.clean();
|
|
1272
|
+
return {
|
|
1273
|
+
UnixTimestamp
|
|
1274
|
+
};
|
|
1275
|
+
}
|
|
1198
1276
|
async createAccessPath(name, path) {
|
|
1199
1277
|
const access = this.environment.getAccessService();
|
|
1200
1278
|
try {
|
|
@@ -1219,11 +1297,13 @@ class FunctionService {
|
|
|
1219
1297
|
}
|
|
1220
1298
|
}
|
|
1221
1299
|
async getCodeParams(options, installDependency) {
|
|
1222
|
-
const { func, functionPath, functionRootPath, base64Code } = options;
|
|
1223
|
-
//
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1300
|
+
const { func, functionPath, functionRootPath, base64Code, deployMode } = options;
|
|
1301
|
+
// 更新的时候直接上传的zip包的情况
|
|
1302
|
+
// ZIP 包大小上限 20MB,base64 编码后长度约为原始大小的 4/3
|
|
1303
|
+
const MAX_ZIP_SIZE = 20 * 1024 * 1024; // 20MB
|
|
1304
|
+
const MAX_BASE64_LENGTH = Math.floor(MAX_ZIP_SIZE * 4 / 3); // ≈ 27962026
|
|
1305
|
+
if ((base64Code === null || base64Code === void 0 ? void 0 : base64Code.length) > MAX_BASE64_LENGTH) {
|
|
1306
|
+
throw new error_1.CloudBaseError('ZIP 包不能大于 20MB');
|
|
1227
1307
|
}
|
|
1228
1308
|
if (base64Code === null || base64Code === void 0 ? void 0 : base64Code.length) {
|
|
1229
1309
|
return {
|
|
@@ -1243,11 +1323,22 @@ class FunctionService {
|
|
|
1243
1323
|
root: functionRootPath
|
|
1244
1324
|
});
|
|
1245
1325
|
await packer.build();
|
|
1246
|
-
//
|
|
1326
|
+
// 如果指定了上传方式,按指定方式上传
|
|
1327
|
+
// 判断是否需要走 COS 上传
|
|
1247
1328
|
const reachMax = await packer.isReachMaxSize();
|
|
1248
|
-
|
|
1249
|
-
|
|
1329
|
+
const useCos = deployMode === 'cos' || (deployMode !== 'zip' && reachMax);
|
|
1330
|
+
if (useCos) {
|
|
1331
|
+
// 先调用scf的 COS 上传方式
|
|
1332
|
+
const legacyResult = await this.uploadFunctionZipToCosLegacy(options, installDependency);
|
|
1333
|
+
// 再调用tcb COS 上传方式
|
|
1334
|
+
const cosResult = await this.uploadFunctionZipToCos(options, installDependency);
|
|
1335
|
+
return {
|
|
1336
|
+
CosTimestamp: cosResult.UnixTimestamp,
|
|
1337
|
+
CosBucketRegion: 'ap-shanghai',
|
|
1338
|
+
TempCosObjectName: `/${legacyResult.Key}`
|
|
1339
|
+
};
|
|
1250
1340
|
}
|
|
1341
|
+
// ZIP base64 上传
|
|
1251
1342
|
const base64 = await packer.getBase64Code();
|
|
1252
1343
|
if (!(base64 === null || base64 === void 0 ? void 0 : base64.length)) {
|
|
1253
1344
|
throw new error_1.CloudBaseError('文件不能为空');
|
|
@@ -1451,6 +1542,9 @@ __decorate([
|
|
|
1451
1542
|
__decorate([
|
|
1452
1543
|
(0, utils_1.preLazy)()
|
|
1453
1544
|
], FunctionService.prototype, "getFunctionAlias", null);
|
|
1545
|
+
__decorate([
|
|
1546
|
+
(0, utils_1.preLazy)()
|
|
1547
|
+
], FunctionService.prototype, "uploadFunctionZipToCosLegacy", null);
|
|
1454
1548
|
__decorate([
|
|
1455
1549
|
(0, utils_1.preLazy)()
|
|
1456
1550
|
], FunctionService.prototype, "uploadFunctionZipToCos", null);
|
package/lib/index.js
CHANGED
|
@@ -18,7 +18,7 @@ class CloudBase {
|
|
|
18
18
|
}
|
|
19
19
|
constructor(config = {}) {
|
|
20
20
|
this.cloudBaseConfig = {};
|
|
21
|
-
let { secretId, secretKey, token, envId, proxy, region, envType } = config;
|
|
21
|
+
let { secretId, secretKey, token, envId, proxy, region, envType, useInternalEndpoint, internalEndpointRegion } = config;
|
|
22
22
|
// config 中传入的 secretId secretkey 必须同时存在
|
|
23
23
|
if ((secretId && !secretKey) || (!secretId && secretKey)) {
|
|
24
24
|
throw new Error('secretId and secretKey must be a pair');
|
|
@@ -30,7 +30,9 @@ class CloudBase {
|
|
|
30
30
|
envId,
|
|
31
31
|
envType,
|
|
32
32
|
proxy,
|
|
33
|
-
region
|
|
33
|
+
region,
|
|
34
|
+
useInternalEndpoint,
|
|
35
|
+
internalEndpointRegion,
|
|
34
36
|
};
|
|
35
37
|
// 初始化 context
|
|
36
38
|
this.context = new context_1.CloudBaseContext(this.cloudBaseConfig);
|
|
@@ -85,5 +87,8 @@ class CloudBase {
|
|
|
85
87
|
getManagerConfig() {
|
|
86
88
|
return this.cloudBaseConfig;
|
|
87
89
|
}
|
|
90
|
+
get isInternalEndpoint() {
|
|
91
|
+
return this.context.isInternalEndpoint();
|
|
92
|
+
}
|
|
88
93
|
}
|
|
89
94
|
module.exports = CloudBase;
|
package/lib/storage/index.js
CHANGED
|
@@ -838,6 +838,7 @@ class StorageService {
|
|
|
838
838
|
* 获取 COS 配置
|
|
839
839
|
*/
|
|
840
840
|
getCos(parallel = 20) {
|
|
841
|
+
const internalEndpoint = this.environment.cloudBaseContext.isInternalEndpoint();
|
|
841
842
|
const { secretId, secretKey, token, proxy } = this.environment.getAuthConfig();
|
|
842
843
|
const cosProxy = process.env.TCB_COS_PROXY;
|
|
843
844
|
const cosConfig = {
|
|
@@ -846,14 +847,14 @@ class StorageService {
|
|
|
846
847
|
SecretKey: secretKey,
|
|
847
848
|
Proxy: cosProxy || proxy,
|
|
848
849
|
SecurityToken: token,
|
|
849
|
-
Domain:
|
|
850
|
+
Domain: internalEndpoint ? "{Bucket}.cos-internal.{Region}.tencentcos.cn" /* COS_ENDPOINT.INTERNAL */ : "{Bucket}.cos.{Region}.tencentcos.cn" /* COS_ENDPOINT.PUBLIC */,
|
|
850
851
|
};
|
|
851
852
|
if (constant_1.COS_SDK_PROTOCOL) {
|
|
852
853
|
cosConfig.Protocol = (constant_1.COS_SDK_PROTOCOL.endsWith(':')
|
|
853
854
|
? constant_1.COS_SDK_PROTOCOL.toLowerCase()
|
|
854
855
|
: constant_1.COS_SDK_PROTOCOL.toLowerCase() + ':');
|
|
855
856
|
}
|
|
856
|
-
if (
|
|
857
|
+
if (internalEndpoint) {
|
|
857
858
|
cosConfig.Protocol = 'http:';
|
|
858
859
|
}
|
|
859
860
|
// COSSDK 默认开启 KeepAlive,这里提供关闭的方式
|
|
@@ -61,6 +61,8 @@ class CloudService {
|
|
|
61
61
|
this.cloudBaseContext = context;
|
|
62
62
|
}
|
|
63
63
|
get baseUrl() {
|
|
64
|
+
const internalEndpoint = this.cloudBaseContext.isInternalEndpoint();
|
|
65
|
+
const internalEndpointRegion = this.cloudBaseContext.getInternalEndpointRegion();
|
|
64
66
|
const tcb = process.env.TCB_BASE_URL || 'https://tcb.tencentcloudapi.com';
|
|
65
67
|
const urlMap = {
|
|
66
68
|
tcb,
|
|
@@ -74,8 +76,11 @@ class CloudService {
|
|
|
74
76
|
const intranetUrlMap = Object.keys(urlMap).map((service) => ({
|
|
75
77
|
[service]: `https://${service}.internal.tencentcloudapi.com`,
|
|
76
78
|
})).reduce((acc, cur) => (Object.assign(Object.assign({}, acc), cur)), {});
|
|
77
|
-
if (
|
|
78
|
-
|
|
79
|
+
if (internalEndpoint) {
|
|
80
|
+
if (internalEndpointRegion) {
|
|
81
|
+
return `https://${this.service}.${internalEndpointRegion}.tencentcloudapi.woa.com`;
|
|
82
|
+
}
|
|
83
|
+
return intranetUrlMap[this.service] || `https://${this.service}.internal.tencentcloudapi.com`;
|
|
79
84
|
}
|
|
80
85
|
if (urlMap[this.service]) {
|
|
81
86
|
return urlMap[this.service];
|
package/package.json
CHANGED
package/types/agent/index.d.ts
CHANGED
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
import { Environment } from '../environment';
|
|
2
|
-
import {
|
|
3
|
-
import { ICreateFunctionAgentParams, ICreateAgentParams, IAgentListItem, IListAgentsParams, IListAgentsResponse, IDeleteAgentParams } from './type';
|
|
2
|
+
import { ICreateFunctionAgentParams } from './type';
|
|
4
3
|
/**
|
|
5
4
|
* Agent 管理类
|
|
6
|
-
* 提供新版 Agent 的完整生命周期管理功能
|
|
7
5
|
*/
|
|
8
6
|
export declare class AgentService {
|
|
9
7
|
private environment;
|
|
10
8
|
private tcbService;
|
|
11
|
-
private scfService;
|
|
12
|
-
private functionService;
|
|
13
|
-
private userService;
|
|
14
9
|
constructor(environment: Environment);
|
|
15
10
|
/**
|
|
16
|
-
* 创建函数型 Agent
|
|
11
|
+
* 创建函数型 Agent
|
|
17
12
|
* @param {string} [cwd=process.cwd()] 工作目录
|
|
18
13
|
* @param {ICreateFunctionAgentParams} agentInfo Agent 信息
|
|
19
14
|
* @returns {Promise<{ BotId: string; RequestId: string }>} Agent 创建结果
|
|
@@ -22,33 +17,4 @@ export declare class AgentService {
|
|
|
22
17
|
BotId: string;
|
|
23
18
|
RequestId: string;
|
|
24
19
|
}>;
|
|
25
|
-
/**
|
|
26
|
-
* 部署新版 Agent 到 web云函数
|
|
27
|
-
* @param {ICreateAgentParams} params 创建参数
|
|
28
|
-
* @returns {Promise<IResponseInfo>} 创建结果
|
|
29
|
-
*/
|
|
30
|
-
deployWebFn(params: ICreateAgentParams, isFirstDeploy?: boolean): Promise<IResponseInfo & {
|
|
31
|
-
AgentId?: string;
|
|
32
|
-
}>;
|
|
33
|
-
/**
|
|
34
|
-
* 获取 Agent 列表
|
|
35
|
-
* @param {IListAgentsParams} [params] 查询参数
|
|
36
|
-
* @returns {Promise<IListAgentsResponse>} Agent 列表
|
|
37
|
-
*/
|
|
38
|
-
list(params?: IListAgentsParams): Promise<IListAgentsResponse>;
|
|
39
|
-
/**
|
|
40
|
-
* 获取 Agent 详情
|
|
41
|
-
* @param {object} params 查询参数
|
|
42
|
-
* @param {string} params.agentId Agent ID
|
|
43
|
-
* @returns {Promise<IAgentDetailResponse>} Agent 详情
|
|
44
|
-
*/
|
|
45
|
-
getAgentInfo(params: {
|
|
46
|
-
agentId: string;
|
|
47
|
-
}): Promise<IAgentListItem | null>;
|
|
48
|
-
/**
|
|
49
|
-
* 删除 Agent
|
|
50
|
-
* @param {IDeleteAgentParams} params 删除参数
|
|
51
|
-
* @returns {Promise<IResponseInfo>} 删除结果
|
|
52
|
-
*/
|
|
53
|
-
delete(params: IDeleteAgentParams): Promise<IResponseInfo>;
|
|
54
20
|
}
|
package/types/agent/type.d.ts
CHANGED
|
@@ -20,357 +20,3 @@ export interface ICreateFunctionAgentParams {
|
|
|
20
20
|
*/
|
|
21
21
|
Avatar?: string;
|
|
22
22
|
}
|
|
23
|
-
export interface IEnvironmentVariable {
|
|
24
|
-
Name: string;
|
|
25
|
-
Value: string;
|
|
26
|
-
}
|
|
27
|
-
export interface IEnvironment {
|
|
28
|
-
Variables: IEnvironmentVariable[];
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Agent 配置接口
|
|
32
|
-
*/
|
|
33
|
-
export interface IAgentConfig {
|
|
34
|
-
/**
|
|
35
|
-
* 函数名称
|
|
36
|
-
*/
|
|
37
|
-
functionName: string;
|
|
38
|
-
/**
|
|
39
|
-
* 代码结构
|
|
40
|
-
*/
|
|
41
|
-
code?: {
|
|
42
|
-
cosBucketRegion?: string;
|
|
43
|
-
cosBucketName?: string;
|
|
44
|
-
cosObjectName?: string;
|
|
45
|
-
tempCosObjectName?: string;
|
|
46
|
-
zipFile?: string;
|
|
47
|
-
};
|
|
48
|
-
/**
|
|
49
|
-
* 超时时间(秒)
|
|
50
|
-
*/
|
|
51
|
-
timeout?: number;
|
|
52
|
-
/**
|
|
53
|
-
* 环境变量
|
|
54
|
-
*/
|
|
55
|
-
environment?: IEnvironment;
|
|
56
|
-
/**
|
|
57
|
-
* 运行时
|
|
58
|
-
*/
|
|
59
|
-
runtime?: string;
|
|
60
|
-
/**
|
|
61
|
-
* 内存大小(MB)
|
|
62
|
-
*/
|
|
63
|
-
memorySize?: number;
|
|
64
|
-
/**
|
|
65
|
-
* 描述
|
|
66
|
-
*/
|
|
67
|
-
description?: string;
|
|
68
|
-
/**
|
|
69
|
-
* 会话配置
|
|
70
|
-
*/
|
|
71
|
-
sessionConfig?: {
|
|
72
|
-
enable: boolean;
|
|
73
|
-
};
|
|
74
|
-
/**
|
|
75
|
-
* 绑定的资源
|
|
76
|
-
*/
|
|
77
|
-
resourceList?: IAgentResource[];
|
|
78
|
-
/**
|
|
79
|
-
* 忽略的文件或目录
|
|
80
|
-
*/
|
|
81
|
-
ignore?: string[];
|
|
82
|
-
installDependency?: boolean;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Agent 资源接口
|
|
86
|
-
*/
|
|
87
|
-
export interface IAgentResource {
|
|
88
|
-
agentId: string;
|
|
89
|
-
/**
|
|
90
|
-
* 资源 ID
|
|
91
|
-
*/
|
|
92
|
-
resourceId: string;
|
|
93
|
-
/**
|
|
94
|
-
* 资源类型
|
|
95
|
-
*/
|
|
96
|
-
resourceType: string;
|
|
97
|
-
/**
|
|
98
|
-
* 子类型
|
|
99
|
-
*/
|
|
100
|
-
subType: string;
|
|
101
|
-
/**
|
|
102
|
-
* 资源配置
|
|
103
|
-
*/
|
|
104
|
-
resourceConfig: {
|
|
105
|
-
apiKey: string;
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Agent 创建参数
|
|
110
|
-
*/
|
|
111
|
-
export interface ICreateAgentParams {
|
|
112
|
-
/**
|
|
113
|
-
* Agent ID
|
|
114
|
-
*/
|
|
115
|
-
agentId?: string;
|
|
116
|
-
/**
|
|
117
|
-
* Agent 名称
|
|
118
|
-
*/
|
|
119
|
-
name: string;
|
|
120
|
-
/**
|
|
121
|
-
* 指定的 Agent 路径
|
|
122
|
-
*/
|
|
123
|
-
agentPath: string;
|
|
124
|
-
/**
|
|
125
|
-
* Agent 根路径
|
|
126
|
-
*/
|
|
127
|
-
agentRootPath: string;
|
|
128
|
-
deployConfig: IAgentConfig;
|
|
129
|
-
}
|
|
130
|
-
export interface ICreateAgentRes {
|
|
131
|
-
/**
|
|
132
|
-
*
|
|
133
|
-
*/
|
|
134
|
-
agentId: string;
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Agent 更新参数
|
|
138
|
-
*/
|
|
139
|
-
export type IUpdateAgentParams = ICreateAgentParams;
|
|
140
|
-
/**
|
|
141
|
-
* Agent 列表查询参数
|
|
142
|
-
*/
|
|
143
|
-
export interface IListAgentsParams {
|
|
144
|
-
/**
|
|
145
|
-
* 每页数量
|
|
146
|
-
*/
|
|
147
|
-
limit?: number;
|
|
148
|
-
/**
|
|
149
|
-
* 偏移量
|
|
150
|
-
*/
|
|
151
|
-
offset?: number;
|
|
152
|
-
/**
|
|
153
|
-
* Agent ID
|
|
154
|
-
*/
|
|
155
|
-
agentId?: string;
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Agent 列表响应
|
|
159
|
-
*/
|
|
160
|
-
export interface IListAgentsResponse {
|
|
161
|
-
/**
|
|
162
|
-
* Agent 列表
|
|
163
|
-
*/
|
|
164
|
-
AgentList: IAgentListItem[];
|
|
165
|
-
/**
|
|
166
|
-
* 总数
|
|
167
|
-
*/
|
|
168
|
-
Total: number;
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Agent 列表项
|
|
172
|
-
*/
|
|
173
|
-
export interface IAgentListItem {
|
|
174
|
-
/**
|
|
175
|
-
* Agent ID
|
|
176
|
-
*/
|
|
177
|
-
AgentId: string;
|
|
178
|
-
/**
|
|
179
|
-
* Agent 名称
|
|
180
|
-
*/
|
|
181
|
-
Name: string;
|
|
182
|
-
/**
|
|
183
|
-
* 状态
|
|
184
|
-
*/
|
|
185
|
-
UpdateTime: string;
|
|
186
|
-
/**
|
|
187
|
-
* 运行时配置
|
|
188
|
-
*/
|
|
189
|
-
RuntimeConfig: IRuntimeConfig;
|
|
190
|
-
}
|
|
191
|
-
export interface IRuntimeConfig {
|
|
192
|
-
Runtime: string;
|
|
193
|
-
MemorySize: number;
|
|
194
|
-
Timeout: number;
|
|
195
|
-
Environment: string;
|
|
196
|
-
SessionConfig: {
|
|
197
|
-
Enable: boolean;
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
export interface IAgentDetailParams {
|
|
201
|
-
agentId: string;
|
|
202
|
-
}
|
|
203
|
-
/**
|
|
204
|
-
* Agent 详情响应
|
|
205
|
-
*/
|
|
206
|
-
export interface IAgentDetailResponse {
|
|
207
|
-
/**
|
|
208
|
-
* Agent ID
|
|
209
|
-
*/
|
|
210
|
-
id: string;
|
|
211
|
-
/**
|
|
212
|
-
* Agent 名称
|
|
213
|
-
*/
|
|
214
|
-
name: string;
|
|
215
|
-
/**
|
|
216
|
-
* 状态
|
|
217
|
-
*/
|
|
218
|
-
status: string;
|
|
219
|
-
/**
|
|
220
|
-
* 运行时
|
|
221
|
-
*/
|
|
222
|
-
runtime: string;
|
|
223
|
-
/**
|
|
224
|
-
* 内存大小(MB)
|
|
225
|
-
*/
|
|
226
|
-
memorySize: number;
|
|
227
|
-
/**
|
|
228
|
-
* 超时时间(秒)
|
|
229
|
-
*/
|
|
230
|
-
timeout: number;
|
|
231
|
-
/**
|
|
232
|
-
* 描述
|
|
233
|
-
*/
|
|
234
|
-
description: string;
|
|
235
|
-
/**
|
|
236
|
-
* 创建时间
|
|
237
|
-
*/
|
|
238
|
-
createTime: string;
|
|
239
|
-
/**
|
|
240
|
-
* 更新时间
|
|
241
|
-
*/
|
|
242
|
-
updateTime: string;
|
|
243
|
-
/**
|
|
244
|
-
* 环境变量
|
|
245
|
-
*/
|
|
246
|
-
environment: IEnvironment;
|
|
247
|
-
/**
|
|
248
|
-
* 会话配置
|
|
249
|
-
*/
|
|
250
|
-
sessionConfig: {
|
|
251
|
-
enable: boolean;
|
|
252
|
-
};
|
|
253
|
-
/**
|
|
254
|
-
* 绑定的资源
|
|
255
|
-
*/
|
|
256
|
-
resources: IAgentResource[];
|
|
257
|
-
/**
|
|
258
|
-
* 部署信息
|
|
259
|
-
*/
|
|
260
|
-
deployInfo?: {
|
|
261
|
-
mode: string;
|
|
262
|
-
version: string;
|
|
263
|
-
codeSize: number;
|
|
264
|
-
lastDeploy: string;
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
/**
|
|
268
|
-
* Agent 删除参数
|
|
269
|
-
*/
|
|
270
|
-
export interface IDeleteAgentParams {
|
|
271
|
-
/**
|
|
272
|
-
* Agent ID
|
|
273
|
-
*/
|
|
274
|
-
agentId: string;
|
|
275
|
-
}
|
|
276
|
-
/**
|
|
277
|
-
* Agent 代码下载参数
|
|
278
|
-
*/
|
|
279
|
-
export interface IDownloadAgentCodeParams {
|
|
280
|
-
/**
|
|
281
|
-
* Agent ID
|
|
282
|
-
*/
|
|
283
|
-
agentId: string;
|
|
284
|
-
/**
|
|
285
|
-
* 目标路径
|
|
286
|
-
*/
|
|
287
|
-
targetPath: string;
|
|
288
|
-
}
|
|
289
|
-
/**
|
|
290
|
-
* 资源绑定参数
|
|
291
|
-
*/
|
|
292
|
-
export interface IBindResourceParams {
|
|
293
|
-
/**
|
|
294
|
-
* Agent ID
|
|
295
|
-
*/
|
|
296
|
-
agentId: string;
|
|
297
|
-
/**
|
|
298
|
-
* 资源列表
|
|
299
|
-
*/
|
|
300
|
-
resourceList: IAgentResource[];
|
|
301
|
-
}
|
|
302
|
-
export interface IBindResourceRes {
|
|
303
|
-
/**
|
|
304
|
-
* 受影响的行数
|
|
305
|
-
*/
|
|
306
|
-
Affected: number;
|
|
307
|
-
}
|
|
308
|
-
/**
|
|
309
|
-
* 资源解绑参数
|
|
310
|
-
*/
|
|
311
|
-
export interface IUnbindResourceParams {
|
|
312
|
-
/**
|
|
313
|
-
* Agent ID
|
|
314
|
-
*/
|
|
315
|
-
agentId: string;
|
|
316
|
-
/**
|
|
317
|
-
* 资源 ID
|
|
318
|
-
*/
|
|
319
|
-
resourceId: string;
|
|
320
|
-
}
|
|
321
|
-
/**
|
|
322
|
-
* 资源解绑响应
|
|
323
|
-
*/
|
|
324
|
-
export interface IUnbindResourceRes {
|
|
325
|
-
/**
|
|
326
|
-
*
|
|
327
|
-
*/
|
|
328
|
-
Affected: number;
|
|
329
|
-
}
|
|
330
|
-
/**
|
|
331
|
-
* 获取资源绑定参数
|
|
332
|
-
*/
|
|
333
|
-
export interface IGetResourceBindingParams {
|
|
334
|
-
/**
|
|
335
|
-
* Agent ID
|
|
336
|
-
*/
|
|
337
|
-
agentId: string;
|
|
338
|
-
/**
|
|
339
|
-
* 资源 ID
|
|
340
|
-
*/
|
|
341
|
-
resourceId: string;
|
|
342
|
-
/**
|
|
343
|
-
* 资源类型
|
|
344
|
-
*/
|
|
345
|
-
resourceType: string;
|
|
346
|
-
}
|
|
347
|
-
/**
|
|
348
|
-
* 获取 Agent 资源参数
|
|
349
|
-
*/
|
|
350
|
-
export interface IGetAgentResourcesParams {
|
|
351
|
-
/**
|
|
352
|
-
* Agent ID
|
|
353
|
-
*/
|
|
354
|
-
agentId: string;
|
|
355
|
-
}
|
|
356
|
-
/**
|
|
357
|
-
* 资源绑定响应
|
|
358
|
-
*/
|
|
359
|
-
export interface IResourceBindingResponse {
|
|
360
|
-
Total: number;
|
|
361
|
-
AgentResourceList: IAgentResource[];
|
|
362
|
-
}
|
|
363
|
-
/**
|
|
364
|
-
* Agent 资源响应
|
|
365
|
-
*/
|
|
366
|
-
export interface IAgentResourcesResponse {
|
|
367
|
-
/**
|
|
368
|
-
* 资源列表
|
|
369
|
-
*/
|
|
370
|
-
resources: IAgentResource[];
|
|
371
|
-
}
|
|
372
|
-
export interface IAgentCodeOptions {
|
|
373
|
-
deployConfig: IAgentConfig;
|
|
374
|
-
agentRootPath?: string;
|
|
375
|
-
agentPath?: string;
|
|
376
|
-
}
|
package/types/constant.d.ts
CHANGED
|
@@ -41,6 +41,7 @@ export declare const SCF_STATUS: {
|
|
|
41
41
|
DELETE_FAILED: string;
|
|
42
42
|
};
|
|
43
43
|
export declare const USE_INTERNAL_ENDPOINT: boolean;
|
|
44
|
+
export declare const INTERNAL_ENDPOINT_REGION: string;
|
|
44
45
|
export declare const enum COS_ENDPOINT {
|
|
45
46
|
INTERNAL = "{Bucket}.cos-internal.{Region}.tencentcos.cn",
|
|
46
47
|
PUBLIC = "{Bucket}.cos.{Region}.tencentcos.cn"
|
package/types/context.d.ts
CHANGED
|
@@ -6,12 +6,18 @@ export declare class CloudBaseContext {
|
|
|
6
6
|
readonly envId: string;
|
|
7
7
|
readonly region: string;
|
|
8
8
|
readonly envType: string;
|
|
9
|
-
|
|
9
|
+
readonly useInternalEndpoint?: boolean;
|
|
10
|
+
readonly internalEndpointRegion?: string;
|
|
11
|
+
constructor({ secretId, secretKey, token, proxy, region, envType, useInternalEndpoint, internalEndpointRegion }: {
|
|
10
12
|
secretId?: string;
|
|
11
13
|
secretKey?: string;
|
|
12
14
|
token?: string;
|
|
13
15
|
proxy?: string;
|
|
14
16
|
region?: string;
|
|
15
17
|
envType?: string;
|
|
18
|
+
useInternalEndpoint?: any;
|
|
19
|
+
internalEndpointRegion?: any;
|
|
16
20
|
});
|
|
21
|
+
isInternalEndpoint(): boolean;
|
|
22
|
+
getInternalEndpointRegion(): string;
|
|
17
23
|
}
|
|
@@ -6,6 +6,7 @@ export interface IFunctionCode {
|
|
|
6
6
|
functionRootPath?: string;
|
|
7
7
|
base64Code?: string;
|
|
8
8
|
functionPath?: string;
|
|
9
|
+
deployMode?: 'cos' | 'zip';
|
|
9
10
|
}
|
|
10
11
|
export interface ICreateFunctionParam {
|
|
11
12
|
func: ICloudFunction & {
|
|
@@ -16,6 +17,7 @@ export interface ICreateFunctionParam {
|
|
|
16
17
|
base64Code?: string;
|
|
17
18
|
functionPath?: string;
|
|
18
19
|
codeSecret?: string;
|
|
20
|
+
deployMode?: 'cos' | 'zip';
|
|
19
21
|
}
|
|
20
22
|
export interface IUpdateFunctionCodeParam {
|
|
21
23
|
func: ICloudFunction;
|
|
@@ -23,6 +25,7 @@ export interface IUpdateFunctionCodeParam {
|
|
|
23
25
|
functionRootPath?: string;
|
|
24
26
|
base64Code?: string;
|
|
25
27
|
codeSecret?: string;
|
|
28
|
+
deployMode?: 'cos' | 'zip';
|
|
26
29
|
}
|
|
27
30
|
export interface IUpdateFunctionIncrementalCodeParam {
|
|
28
31
|
func: ICloudFunction;
|
|
@@ -479,9 +482,20 @@ export declare class FunctionService {
|
|
|
479
482
|
* @memberof FunctionService
|
|
480
483
|
*/
|
|
481
484
|
getFunctionAlias(params: IGetFunctionAlias): Promise<IGetFunctionAliasRes>;
|
|
482
|
-
|
|
485
|
+
/**
|
|
486
|
+
* 通过scf COS 上传方式(通过 GetTempCosInfo + COS SDK 上传)
|
|
487
|
+
* 返回 TempCosObjectName 用于创建/更新函数
|
|
488
|
+
*/
|
|
489
|
+
uploadFunctionZipToCosLegacy(options: IFunctionCode, installDependency: 'TRUE' | 'FALSE'): Promise<{
|
|
483
490
|
Key: string;
|
|
484
491
|
}>;
|
|
492
|
+
/**
|
|
493
|
+
* 新的 COS 上传方式(通过 DescribeBuildServiceCosInfo + PUT 上传)
|
|
494
|
+
* 返回 CosTimestamp 用于创建/更新函数
|
|
495
|
+
*/
|
|
496
|
+
uploadFunctionZipToCos(options: IFunctionCode, installDependency: 'TRUE' | 'FALSE'): Promise<{
|
|
497
|
+
UnixTimestamp: string;
|
|
498
|
+
}>;
|
|
485
499
|
private createAccessPath;
|
|
486
500
|
private getCodeParams;
|
|
487
501
|
private getTempCosInfo;
|
|
@@ -181,7 +181,10 @@ export interface ITag1 {
|
|
|
181
181
|
export interface IFunctionCode {
|
|
182
182
|
CosBucketName?: string;
|
|
183
183
|
CosObjectName?: string;
|
|
184
|
-
|
|
184
|
+
CosBucketRegion?: string;
|
|
185
|
+
TempCosObjectName?: string;
|
|
186
|
+
ZipFile?: string;
|
|
187
|
+
CosTimestamp?: string;
|
|
185
188
|
}
|
|
186
189
|
export interface ILayerVersionItem {
|
|
187
190
|
LayerName: string;
|
package/types/index.d.ts
CHANGED
|
@@ -20,6 +20,8 @@ interface CloudBaseConfig {
|
|
|
20
20
|
proxy?: string;
|
|
21
21
|
region?: string;
|
|
22
22
|
envType?: string;
|
|
23
|
+
useInternalEndpoint?: boolean;
|
|
24
|
+
internalEndpointRegion?: string;
|
|
23
25
|
}
|
|
24
26
|
declare class CloudBase {
|
|
25
27
|
private static cloudBase;
|
|
@@ -52,5 +54,6 @@ declare class CloudBase {
|
|
|
52
54
|
get user(): UserService;
|
|
53
55
|
getEnvironmentManager(): EnvironmentManager;
|
|
54
56
|
getManagerConfig(): CloudBaseConfig;
|
|
57
|
+
get isInternalEndpoint(): Boolean;
|
|
55
58
|
}
|
|
56
59
|
export = CloudBase;
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
cloudbaseAIVersion:1.8.20
|
|
3
|
-
description: CloudBase AI 开发规则索引 - 防止不同开发场景的规则互相干扰
|
|
4
|
-
globs:
|
|
5
|
-
alwaysApply: true
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# AI 开发人机协同规则索引
|
|
9
|
-
|
|
10
|
-
## 核心行为规则
|
|
11
|
-
0. 你擅长调用合适的工具来完成完成各项任务
|
|
12
|
-
1. 你会在对话输出完毕后选择适当的时机向用户提出询问,例如是否需要添加后端能力,是否打开预览,是否需要部署等
|
|
13
|
-
2. 你首先会阅读当前项目的 README.md,遵照当前项目的说明进行开发,如果不存在则会在生成项目后生成一个 README.md 文件
|
|
14
|
-
3. 开发的时候,默认就在当前目录下产出所有项目代码,先检查当前目录的文件
|
|
15
|
-
4. 开发预览的时候,如果本身项目有依赖后端数据库集合和云函数,可以优先部署后端然后再预览前端
|
|
16
|
-
5. 交互式反馈规则:在需求不明确时主动与用户对话澄清,优先使用自动化工具 interactiveDialog 完成配置。执行高风险操作前必须使用 interactiveDialog 获得用户确认。保持消息简洁并用emoji标记状态。
|
|
17
|
-
6. 如果涉及到实时通信相关的例如实时对战等,可以使用云开发的实时数据库 watch 能力
|
|
18
|
-
|
|
19
|
-
## 工作流
|
|
20
|
-
|
|
21
|
-
<workflow>
|
|
22
|
-
0. 请注意!必须遵守以下的规则,每个环节完成后都需要由我进行确认后才可进行下一个环节;
|
|
23
|
-
1. 如果你判断我的输入提出的是一个新需求,可以按照下面的标准软件工程的方式独立开展工作,需要时才向我询问,可以采用 interactiveDialog 工具来收集
|
|
24
|
-
2. 每当我输入新的需求的时候,为了规范需求质量和验收标准,你首先会搞清楚问题和需求,然后再进入下一阶段
|
|
25
|
-
3. 需求文档和验收标准设计:首先完成需求的设计,按照 EARS 简易需求语法方法来描述,跟我进行确认,最终确认清楚后,需求定稿,然后再进入下一阶段,保存在 `specs/spec_name/requirements.md` 中,参考格式如下
|
|
26
|
-
|
|
27
|
-
```markdown
|
|
28
|
-
# 需求文档
|
|
29
|
-
|
|
30
|
-
## 介绍
|
|
31
|
-
|
|
32
|
-
需求描述
|
|
33
|
-
|
|
34
|
-
## 需求
|
|
35
|
-
|
|
36
|
-
### 需求 1 - 需求名称
|
|
37
|
-
|
|
38
|
-
**用户故事:** 用户故事内容
|
|
39
|
-
|
|
40
|
-
#### 验收标准
|
|
41
|
-
|
|
42
|
-
1. 采用 ERAS 描述的子句 While <可选前置条件>, when <可选触发器>, the <系统名称> shall <系统响应>,例如 When 选择"静音"时,笔记本电脑应当抑制所有音频输出。
|
|
43
|
-
2. ...
|
|
44
|
-
...
|
|
45
|
-
```
|
|
46
|
-
4. 技术方案设计: 在完成需求的设计之后,你会根据当前的技术架构和前面确认好的需求,进行需求的技术方案设计,精简但是能够准确的描述技术的架构(例如架构、技术栈、技术选型、数据库/接口设计、测试策略、安全性),必要时可以用 mermaid 来绘图,跟我确认清楚后,保存在 `specs/spec_name/design.md` 中,然后再进入下一阶段
|
|
47
|
-
5. 任务拆分:在完成技术方案设计后,你会根据需求文档和技术方案,细化具体要做的事情,跟我确认清楚后,,保存在`specs/spec_name/tasks.md` 中, 然后再进入下一阶段,开始正式执行任务,同时需要及时更新任务的状态,执行的时候尽可能独立自主运行,保证效率和质量
|
|
48
|
-
|
|
49
|
-
任务参考格式如下
|
|
50
|
-
|
|
51
|
-
``` markdown
|
|
52
|
-
# 实施计划
|
|
53
|
-
|
|
54
|
-
- [ ] 1. 任务信息
|
|
55
|
-
- 具体要做的事情
|
|
56
|
-
- ...
|
|
57
|
-
- _需求: 相关的需求点的编号
|
|
58
|
-
|
|
59
|
-
```
|
|
60
|
-
</workflow>
|
|
61
|
-
|
|
62
|
-
## 专业领域规则文件
|
|
63
|
-
|
|
64
|
-
**重要:根据具体的开发场景,AI 必须参考对应的规则文件,避免不同场景的规则互相干扰**
|
|
65
|
-
|
|
66
|
-
### rules/web-development.mdc
|
|
67
|
-
描述前端+云开发 CloudBase 项目开发的专业规则,包含:
|
|
68
|
-
- Web 项目结构和工程化配置
|
|
69
|
-
- 静态托管部署流程
|
|
70
|
-
- Web SDK 使用和认证方式
|
|
71
|
-
- 适用于纯 Web 项目开发时参考
|
|
72
|
-
|
|
73
|
-
### rules/miniprogram-development.mdc
|
|
74
|
-
描述微信小程序开发的专业规则,包含:
|
|
75
|
-
- 小程序项目结构和配置
|
|
76
|
-
- 微信云开发能力集成
|
|
77
|
-
- 小程序特有的 API 和权限处理
|
|
78
|
-
- 适用于微信小程序开发时参考
|
|
79
|
-
|
|
80
|
-
### rules/cloudbase-platform.mdc
|
|
81
|
-
描述 CloudBase 平台的核心知识,包含:
|
|
82
|
-
- 云开发环境和认证
|
|
83
|
-
- 云函数、数据库、存储等服务
|
|
84
|
-
- 数据模型和权限管理
|
|
85
|
-
- 控制台管理页面链接
|
|
86
|
-
- 适用于所有使用 CloudBase 平台的项目
|
|
87
|
-
|
|
88
|
-
### rules/workflows.mdc
|
|
89
|
-
描述开发工作流程,包含:
|
|
90
|
-
- 部署流程(云函数、静态托管)
|
|
91
|
-
- 素材下载和知识库查询
|
|
92
|
-
- 文档和配置文件生成规则
|
|
93
|
-
- MCP 接口调用规范
|
|
94
|
-
- 适用于项目开发的各个阶段
|
|
95
|
-
|
|
96
|
-
### rules/database.mdc
|
|
97
|
-
描述云开发 CloudBase 数据库操作的专业规则,包含:
|
|
98
|
-
- CloudBase 数据库操作注意事项
|
|
99
|
-
- 数据库权限管理
|
|
100
|
-
- 数据更新和错误处理
|
|
101
|
-
- 适用于涉及数据库操作的项目
|
|
102
|
-
|
|
103
|
-
### rules/ui-design.mdc
|
|
104
|
-
描述web/小程序等页面设计和 UI 规范,包含:
|
|
105
|
-
- 高保真原型设计流程
|
|
106
|
-
- UI 设计规范和工具选择
|
|
107
|
-
- 前端样式处理
|
|
108
|
-
- 适用于需要设计界面的项目
|
|
109
|
-
|
|
110
|
-
## 使用指导
|
|
111
|
-
- **Web 项目开发**:主要参考 `rules/web-development.mdc` + `rules/cloudbase-platform.mdc` + `rules/workflows.mdc`
|
|
112
|
-
- **微信小程序开发**:主要参考 `rules/miniprogram-development.mdc` + `rules/cloudbase-platform.mdc` + `rules/workflows.mdc`
|
|
113
|
-
- **数据库相关**:额外参考 `rules/database.mdc`
|
|
114
|
-
- **UI 设计需求**:额外参考 `rules/ui-design.mdc`
|
|
115
|
-
|
|
116
|
-
**重要提醒:开发微信小程序时,严禁参考 Web SDK 的认证方式,必须使用小程序专用的 API 和云开发方式!**
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|