@cloudbase/manager-node 4.10.1 → 4.10.3-beta.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/lib/function/index.js +364 -152
- package/lib/storage/index.js +37 -9
- package/package.json +1 -1
- package/types/function/index.d.ts +4 -4
- package/types/function/types.d.ts +37 -9
- package/types/interfaces/function.interface.d.ts +28 -3
- package/types/storage/index.d.ts +27 -6
package/lib/function/index.js
CHANGED
|
@@ -23,90 +23,202 @@ function isNodeFunction(runtime) {
|
|
|
23
23
|
// 不严格限制
|
|
24
24
|
return runtime === 'Nodejs10.15' || runtime === 'Nodejs8.9' || (runtime === null || runtime === void 0 ? void 0 : runtime.includes('Nodejs'));
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
/**
|
|
27
|
+
* 构建镜像配置对象
|
|
28
|
+
* @param imageConfig 镜像配置
|
|
29
|
+
* @returns 构建好的镜像配置对象
|
|
30
|
+
*/
|
|
31
|
+
function buildImageConfig(imageConfig) {
|
|
32
|
+
// 先转换大小写
|
|
33
|
+
const config = toPascalCaseKeys(imageConfig);
|
|
34
|
+
// 再补充默认值
|
|
35
|
+
return Object.assign({ ImageType: 'enterprise', ImagePort: 9000 }, config);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* 递归转换对象的 key 从 camelCase 到 PascalCase
|
|
39
|
+
*/
|
|
40
|
+
function toPascalCaseKeys(obj) {
|
|
41
|
+
if (obj === null || obj === undefined)
|
|
42
|
+
return obj;
|
|
43
|
+
if (Array.isArray(obj))
|
|
44
|
+
return obj.map(item => toPascalCaseKeys(item));
|
|
45
|
+
if (typeof obj !== 'object')
|
|
46
|
+
return obj;
|
|
47
|
+
const result = {};
|
|
48
|
+
for (const key of Object.keys(obj)) {
|
|
49
|
+
// 通用规则:首字母大写
|
|
50
|
+
const pascalKey = key.charAt(0).toUpperCase() + key.slice(1);
|
|
51
|
+
result[pascalKey] = toPascalCaseKeys(obj[key]);
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* 将布尔值转换为 API 需要的 'TRUE'/'FALSE' 字符串
|
|
57
|
+
* 支持 boolean | string | undefined 输入
|
|
58
|
+
* @param value 输入值
|
|
59
|
+
* @returns 'TRUE' | 'FALSE' | undefined
|
|
60
|
+
*/
|
|
61
|
+
function toBooleanString(value) {
|
|
62
|
+
if (value === undefined)
|
|
63
|
+
return undefined;
|
|
64
|
+
// 已经是字符串格式
|
|
65
|
+
if (value === 'TRUE' || value === 'FALSE')
|
|
66
|
+
return value;
|
|
67
|
+
// 字符串 'true'/'false' 兼容
|
|
68
|
+
if (typeof value === 'string') {
|
|
69
|
+
return value.toUpperCase() === 'TRUE' ? 'TRUE' : 'FALSE';
|
|
70
|
+
}
|
|
71
|
+
// 布尔值转换
|
|
72
|
+
return value ? 'TRUE' : 'FALSE';
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* 大小写不敏感获取对象字段值
|
|
76
|
+
* @param obj 目标对象
|
|
77
|
+
* @param fieldName 字段名(任意大小写)
|
|
78
|
+
* @returns 字段值,找不到返回 undefined
|
|
79
|
+
*/
|
|
80
|
+
function getFieldIgnoreCase(obj, fieldName) {
|
|
81
|
+
if (!obj || typeof obj !== 'object')
|
|
82
|
+
return undefined;
|
|
83
|
+
const lowerFieldName = fieldName.toLowerCase();
|
|
84
|
+
for (const key of Object.keys(obj)) {
|
|
85
|
+
if (key.toLowerCase() === lowerFieldName) {
|
|
86
|
+
return obj[key];
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
// 解析函数配置,换成请求参数(用于 CreateFunction)
|
|
27
92
|
function configToParams(options) {
|
|
28
|
-
var _a, _b, _c
|
|
29
|
-
const { func, codeSecret, baseParams } = options;
|
|
30
|
-
|
|
31
|
-
//
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
params
|
|
56
|
-
//
|
|
57
|
-
|
|
93
|
+
var _a, _b, _c;
|
|
94
|
+
const { func, codeSecret, baseParams = {} } = options;
|
|
95
|
+
// 白名单:只有这些字段会被透传到 API(大小写不敏感)
|
|
96
|
+
// 参考 SCF API 文档:https://cloud.tencent.com/document/product/583/18586
|
|
97
|
+
// key: 小写用于匹配,value: PascalCase 用于输出
|
|
98
|
+
const AUTO_CONVERT_FIELDS = {
|
|
99
|
+
// 基础配置
|
|
100
|
+
'description': 'Description',
|
|
101
|
+
'memorysize': 'MemorySize',
|
|
102
|
+
'timeout': 'Timeout',
|
|
103
|
+
'runtime': 'Runtime',
|
|
104
|
+
'type': 'Type', // Event/HTTP
|
|
105
|
+
'role': 'Role',
|
|
106
|
+
// 日志配置
|
|
107
|
+
'clslogsetid': 'ClsLogsetId',
|
|
108
|
+
'clstopicid': 'ClsTopicId',
|
|
109
|
+
// 高级配置
|
|
110
|
+
'deadletterconfig': 'DeadLetterConfig',
|
|
111
|
+
'publicnetconfig': 'PublicNetConfig',
|
|
112
|
+
'cfsconfig': 'CfsConfig',
|
|
113
|
+
'inittimeout': 'InitTimeout',
|
|
114
|
+
'tags': 'Tags',
|
|
115
|
+
// 注意:asyncRunEnable/traceEnable/autoDeployClsTopicIndex/autoCreateClsTopic/dnsCache
|
|
116
|
+
// 需要 'TRUE'/'FALSE' 字符串,在特殊处理阶段处理
|
|
117
|
+
'protocoltype': 'ProtocolType', // WS
|
|
118
|
+
'intranetconfig': 'IntranetConfig',
|
|
119
|
+
};
|
|
120
|
+
let params = Object.assign(Object.assign({}, baseParams), { FunctionName: func.name });
|
|
121
|
+
// 第一阶段:白名单字段自动转换(大小写不敏感,统一输出 PascalCase)
|
|
122
|
+
for (const key of Object.keys(func)) {
|
|
123
|
+
const lowerKey = key.toLowerCase();
|
|
124
|
+
const pascalKey = AUTO_CONVERT_FIELDS[lowerKey];
|
|
125
|
+
if (!pascalKey || func[key] === undefined)
|
|
126
|
+
continue;
|
|
127
|
+
params[pascalKey] = toPascalCaseKeys(func[key]);
|
|
128
|
+
}
|
|
129
|
+
// 第二阶段:特殊处理字段
|
|
130
|
+
// 1. 安装依赖标志(支持 boolean | string)
|
|
131
|
+
if (func.installDependency !== undefined) {
|
|
132
|
+
params.InstallDependency = toBooleanString(func.installDependency);
|
|
133
|
+
}
|
|
134
|
+
// 2. L5 配置 - 当不存在时不修改,否则根据 true/false 进行修改
|
|
135
|
+
if (func.l5 !== undefined) {
|
|
136
|
+
params.L5Enable = toBooleanString(func.l5);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
params.L5Enable = null;
|
|
140
|
+
}
|
|
141
|
+
// 3. 需要 'TRUE'/'FALSE' 字符串的布尔字段统一处理(大小写不敏感)
|
|
142
|
+
// key: 小写用于匹配,value: PascalCase 用于输出
|
|
143
|
+
const BOOLEAN_STRING_FIELDS = {
|
|
144
|
+
'asyncrunenable': 'AsyncRunEnable', // 异步属性
|
|
145
|
+
'traceenable': 'TraceEnable', // 事件追踪
|
|
146
|
+
'autodeployclstopicindex': 'AutoDeployClsTopicIndex', // 自动创建 CLS 索引
|
|
147
|
+
'autocreateclstopic': 'AutoCreateClsTopic', // 自动创建 CLS 主题
|
|
148
|
+
'dnscache': 'DnsCache', // Dns 缓存
|
|
149
|
+
};
|
|
150
|
+
for (const key of Object.keys(func)) {
|
|
151
|
+
const lowerKey = key.toLowerCase();
|
|
152
|
+
const pascalKey = BOOLEAN_STRING_FIELDS[lowerKey];
|
|
153
|
+
if (pascalKey && func[key] !== undefined) {
|
|
154
|
+
params[pascalKey] = toBooleanString(func[key]);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// 5. 环境变量 - 为覆盖式修改,不保留已有字段
|
|
158
|
+
if (func.envVariables && Object.keys(func.envVariables).length > 0) {
|
|
159
|
+
params.Environment = {
|
|
160
|
+
Variables: Object.keys(func.envVariables).map(key => ({
|
|
161
|
+
Key: key,
|
|
162
|
+
Value: func.envVariables[key]
|
|
163
|
+
}))
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
// 4. 函数角色(如果白名单已处理则跳过)
|
|
167
|
+
if (!params.Role && func.role) {
|
|
168
|
+
params.Role = func.role;
|
|
169
|
+
}
|
|
170
|
+
// 5. VPC 配置
|
|
58
171
|
if (((_a = func === null || func === void 0 ? void 0 : func.vpc) === null || _a === void 0 ? void 0 : _a.subnetId) !== undefined && ((_b = func === null || func === void 0 ? void 0 : func.vpc) === null || _b === void 0 ? void 0 : _b.vpcId) !== undefined) {
|
|
59
|
-
// VPC 网络
|
|
60
172
|
params.VpcConfig = {
|
|
61
|
-
SubnetId:
|
|
62
|
-
VpcId:
|
|
173
|
+
SubnetId: func.vpc.subnetId,
|
|
174
|
+
VpcId: func.vpc.vpcId
|
|
63
175
|
};
|
|
64
176
|
}
|
|
65
|
-
//
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
params.InstallDependency = installDependency;
|
|
69
|
-
// 代码保护
|
|
70
|
-
if (codeSecret || func.codeSecret) {
|
|
71
|
-
params.CodeSecret = codeSecret || func.codeSecret;
|
|
72
|
-
}
|
|
73
|
-
// 函数层
|
|
74
|
-
if ((_e = func === null || func === void 0 ? void 0 : func.layers) === null || _e === void 0 ? void 0 : _e.length) {
|
|
75
|
-
const transformLayers = func.layers.map(item => ({
|
|
177
|
+
// 6. 函数层
|
|
178
|
+
if ((_c = func === null || func === void 0 ? void 0 : func.layers) === null || _c === void 0 ? void 0 : _c.length) {
|
|
179
|
+
params.Layers = func.layers.map(item => ({
|
|
76
180
|
LayerName: item.name,
|
|
77
181
|
LayerVersion: item.version
|
|
78
182
|
}));
|
|
79
|
-
params.Layers = transformLayers;
|
|
80
183
|
}
|
|
81
|
-
//
|
|
82
|
-
if (
|
|
83
|
-
params.
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
184
|
+
// 7. 代码保护
|
|
185
|
+
if (codeSecret || func.codeSecret) {
|
|
186
|
+
params.CodeSecret = codeSecret || func.codeSecret;
|
|
187
|
+
}
|
|
188
|
+
// 8. 协议参数(WebSocket,大小写不敏感)
|
|
189
|
+
const protocolParams = getFieldIgnoreCase(func, 'protocolParams');
|
|
190
|
+
if (protocolParams) {
|
|
191
|
+
const wsParams = getFieldIgnoreCase(protocolParams, 'wsParams');
|
|
192
|
+
if (wsParams) {
|
|
90
193
|
params.ProtocolParams = {
|
|
91
|
-
WSParams:
|
|
92
|
-
IdleTimeOut: typeof idleTimeOut === 'number' ? idleTimeOut : 15
|
|
93
|
-
}
|
|
194
|
+
WSParams: toPascalCaseKeys(wsParams)
|
|
94
195
|
};
|
|
95
196
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
197
|
+
}
|
|
198
|
+
// 9. HTTP 云函数特殊处理(type 字段大小写不敏感)
|
|
199
|
+
const funcType = getFieldIgnoreCase(func, 'type');
|
|
200
|
+
if ((funcType === null || funcType === void 0 ? void 0 : funcType.toUpperCase()) === 'HTTP') {
|
|
201
|
+
params.Type = 'HTTP';
|
|
202
|
+
// 多并发配置 - 仅 HTTP 函数支持(大小写不敏感)
|
|
203
|
+
const instanceConcurrencyConfig = getFieldIgnoreCase(func, 'instanceConcurrencyConfig');
|
|
204
|
+
if (instanceConcurrencyConfig) {
|
|
205
|
+
const config = toPascalCaseKeys(instanceConcurrencyConfig);
|
|
206
|
+
// DynamicEnabled 需要特殊处理为 'TRUE'/'FALSE'
|
|
207
|
+
if (config.DynamicEnabled !== undefined) {
|
|
208
|
+
config.DynamicEnabled = toBooleanString(config.DynamicEnabled);
|
|
209
|
+
}
|
|
210
|
+
params.InstanceConcurrencyConfig = config;
|
|
103
211
|
}
|
|
104
212
|
}
|
|
105
|
-
//
|
|
106
|
-
|
|
107
|
-
|
|
213
|
+
// 10. 镜像配置(用于镜像部署,大小写不敏感)
|
|
214
|
+
const imageConfig = getFieldIgnoreCase(func, 'imageConfig');
|
|
215
|
+
if (imageConfig) {
|
|
216
|
+
params.Code = params.Code || {};
|
|
217
|
+
params.Code.ImageConfig = buildImageConfig(imageConfig);
|
|
108
218
|
}
|
|
109
|
-
|
|
219
|
+
// 第三阶段:统一应用默认值
|
|
220
|
+
const runtime = params.Runtime || 'Nodejs18.15';
|
|
221
|
+
return Object.assign({ Handler: func.handler || 'index.main', Timeout: 10, Runtime: 'Nodejs18.15', MemorySize: 256, InstallDependency: isNodeFunction(runtime) ? 'TRUE' : 'FALSE' }, params);
|
|
110
222
|
}
|
|
111
223
|
class FunctionService {
|
|
112
224
|
constructor(environment) {
|
|
@@ -123,12 +235,11 @@ class FunctionService {
|
|
|
123
235
|
* @memberof FunctionService
|
|
124
236
|
*/
|
|
125
237
|
async updateFunctionIncrementalCode(funcParam) {
|
|
126
|
-
const {
|
|
238
|
+
const { namespace } = this.getFunctionConfig();
|
|
127
239
|
const { functionRootPath, func, deleteFiles, addFiles } = funcParam;
|
|
128
240
|
const { name, runtime } = func;
|
|
129
241
|
const params = {
|
|
130
242
|
FunctionName: name,
|
|
131
|
-
EnvId: env,
|
|
132
243
|
Namespace: namespace
|
|
133
244
|
};
|
|
134
245
|
let packer;
|
|
@@ -153,7 +264,7 @@ class FunctionService {
|
|
|
153
264
|
}
|
|
154
265
|
params.AddFiles = base64;
|
|
155
266
|
}
|
|
156
|
-
return this.
|
|
267
|
+
return this.scfService.request('UpdateFunctionIncrementalCode', params);
|
|
157
268
|
}
|
|
158
269
|
/**
|
|
159
270
|
* 创建云函数
|
|
@@ -161,31 +272,49 @@ class FunctionService {
|
|
|
161
272
|
* @returns {(Promise<IResponseInfo | ICreateFunctionRes>)}
|
|
162
273
|
*/
|
|
163
274
|
async createFunction(funcParam) {
|
|
164
|
-
|
|
275
|
+
var _a, _b, _c;
|
|
276
|
+
const { namespace } = this.getFunctionConfig();
|
|
165
277
|
const { func, functionRootPath, force = false, base64Code, codeSecret, functionPath, deployMode } = funcParam;
|
|
166
278
|
const funcName = func.name;
|
|
167
279
|
const params = configToParams({
|
|
168
280
|
func,
|
|
169
281
|
codeSecret,
|
|
170
282
|
baseParams: {
|
|
171
|
-
|
|
283
|
+
Namespace: namespace,
|
|
172
284
|
Role: 'TCB_QcsRole',
|
|
173
285
|
Stamp: 'MINI_QCBASE'
|
|
174
286
|
}
|
|
175
287
|
});
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
288
|
+
// 根据部署方式处理 Code 参数
|
|
289
|
+
// 优先使用显式指定的 deployMode,如果未指定但存在 imageConfig 则认为是镜像部署
|
|
290
|
+
const isImageDeploy = deployMode === 'image' || (!deployMode && ((_a = params.Code) === null || _a === void 0 ? void 0 : _a.ImageConfig));
|
|
291
|
+
if (isImageDeploy) {
|
|
292
|
+
// 镜像部署:Code 参数已在 configToParams 中通过 imageConfig 设置
|
|
293
|
+
if (!((_c = (_b = params.Code) === null || _b === void 0 ? void 0 : _b.ImageConfig) === null || _c === void 0 ? void 0 : _c.ImageUri)) {
|
|
294
|
+
throw new error_1.CloudBaseError('镜像部署需要配置 imageConfig.imageUri');
|
|
295
|
+
}
|
|
296
|
+
// 镜像部署的特殊配置
|
|
297
|
+
// 镜像函数不需要 Handler
|
|
298
|
+
delete params.Handler;
|
|
299
|
+
// 镜像函数不需要安装依赖
|
|
300
|
+
delete params.InstallDependency;
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
// 代码部署:通过 getCodeParams 获取代码参数
|
|
304
|
+
params.Code = await this.getCodeParams({
|
|
305
|
+
func,
|
|
306
|
+
base64Code,
|
|
307
|
+
functionPath,
|
|
308
|
+
functionRootPath,
|
|
309
|
+
deployMode
|
|
310
|
+
}, params.InstallDependency);
|
|
311
|
+
}
|
|
183
312
|
const { TopicId, LogsetId } = this.getClsServiceConfig();
|
|
184
313
|
params.ClsTopicId = TopicId;
|
|
185
314
|
params.ClsLogsetId = LogsetId;
|
|
186
315
|
try {
|
|
187
316
|
// 创建云函数
|
|
188
|
-
const res = await this.
|
|
317
|
+
const res = await this.scfService.request('CreateFunction', params);
|
|
189
318
|
// 等待函数状态正常
|
|
190
319
|
await this.waitFunctionActive(funcName, codeSecret);
|
|
191
320
|
// 创建函数触发器、失败自动重试
|
|
@@ -203,13 +332,14 @@ class FunctionService {
|
|
|
203
332
|
const functionExist = e.code === 'ResourceInUse.FunctionName' || e.code === 'ResourceInUse.Function';
|
|
204
333
|
// 已存在同名函数,强制更新
|
|
205
334
|
if (functionExist && force) {
|
|
206
|
-
// 1.
|
|
335
|
+
// 1. 更新函数代码(通过 deployMode 区分镜像部署和代码部署)
|
|
207
336
|
const codeRes = await this.updateFunctionCode({
|
|
208
337
|
func,
|
|
209
338
|
base64Code,
|
|
210
339
|
functionPath,
|
|
211
340
|
functionRootPath,
|
|
212
|
-
codeSecret: codeSecret
|
|
341
|
+
codeSecret: codeSecret,
|
|
342
|
+
deployMode: isImageDeploy ? 'image' : undefined
|
|
213
343
|
});
|
|
214
344
|
// 等待函数状态正常
|
|
215
345
|
await this.waitFunctionActive(funcName, codeSecret);
|
|
@@ -254,9 +384,9 @@ class FunctionService {
|
|
|
254
384
|
*/
|
|
255
385
|
async getFunctionList(limit = 20, offset = 0) {
|
|
256
386
|
// 获取Function 环境配置
|
|
257
|
-
const {
|
|
258
|
-
const res = await this.
|
|
259
|
-
|
|
387
|
+
const { namespace } = this.getFunctionConfig();
|
|
388
|
+
const res = await this.scfService.request('ListFunctions', {
|
|
389
|
+
Namespace: namespace,
|
|
260
390
|
Limit: limit,
|
|
261
391
|
Offset: offset
|
|
262
392
|
});
|
|
@@ -270,9 +400,9 @@ class FunctionService {
|
|
|
270
400
|
*/
|
|
271
401
|
async listFunctions(limit = 20, offset = 0) {
|
|
272
402
|
// 获取Function 环境配置
|
|
273
|
-
const {
|
|
274
|
-
const res = await this.
|
|
275
|
-
|
|
403
|
+
const { namespace } = this.getFunctionConfig();
|
|
404
|
+
const res = await this.scfService.request('ListFunctions', {
|
|
405
|
+
Namespace: namespace,
|
|
276
406
|
Limit: limit,
|
|
277
407
|
Offset: offset
|
|
278
408
|
});
|
|
@@ -303,8 +433,8 @@ class FunctionService {
|
|
|
303
433
|
const { envId } = options;
|
|
304
434
|
while (true) {
|
|
305
435
|
try {
|
|
306
|
-
const res = await this.
|
|
307
|
-
|
|
436
|
+
const res = await this.scfService.request('ListFunctions', {
|
|
437
|
+
Namespace: envId,
|
|
308
438
|
Limit: pageSize,
|
|
309
439
|
Offset: currentOffset
|
|
310
440
|
});
|
|
@@ -387,17 +517,16 @@ class FunctionService {
|
|
|
387
517
|
* @returns {Promise<Record<string, string>>}
|
|
388
518
|
*/
|
|
389
519
|
async getFunctionDetail(name, codeSecret) {
|
|
390
|
-
const {
|
|
520
|
+
const { namespace } = this.getFunctionConfig();
|
|
391
521
|
const params = {
|
|
392
522
|
FunctionName: name,
|
|
393
|
-
EnvId: env,
|
|
394
523
|
ShowCode: 'TRUE',
|
|
395
|
-
Namespace:
|
|
524
|
+
Namespace: namespace
|
|
396
525
|
};
|
|
397
526
|
if (codeSecret) {
|
|
398
527
|
params.CodeSecret = codeSecret;
|
|
399
528
|
}
|
|
400
|
-
const data = await this.
|
|
529
|
+
const data = await this.scfService.request('GetFunction', params);
|
|
401
530
|
// 解析 VPC 配置
|
|
402
531
|
const { VpcId = '', SubnetId = '' } = data.VpcConfig || {};
|
|
403
532
|
if (VpcId && SubnetId) {
|
|
@@ -574,67 +703,110 @@ class FunctionService {
|
|
|
574
703
|
* @returns {Promise<IResponseInfo>}
|
|
575
704
|
*/
|
|
576
705
|
async updateFunctionConfig(func) {
|
|
577
|
-
var _a, _b, _c
|
|
706
|
+
var _a, _b, _c;
|
|
578
707
|
const { namespace } = this.getFunctionConfig();
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
708
|
+
// UpdateFunctionConfiguration API 白名单(大小写不敏感)
|
|
709
|
+
// 参考:https://cloud.tencent.com/document/product/583/18580
|
|
710
|
+
// 注意:Runtime, Handler, Code, Type, ProtocolType 只能在 CreateFunction 时指定
|
|
711
|
+
// key: 小写用于匹配,value: PascalCase 用于输出
|
|
712
|
+
const UPDATE_CONFIG_FIELDS = {
|
|
713
|
+
'description': 'Description',
|
|
714
|
+
'memorysize': 'MemorySize',
|
|
715
|
+
'timeout': 'Timeout',
|
|
716
|
+
'role': 'Role',
|
|
717
|
+
// 日志配置
|
|
718
|
+
'clslogsetid': 'ClsLogsetId',
|
|
719
|
+
'clstopicid': 'ClsTopicId',
|
|
720
|
+
// 高级配置
|
|
721
|
+
'deadletterconfig': 'DeadLetterConfig',
|
|
722
|
+
'publicnetconfig': 'PublicNetConfig',
|
|
723
|
+
'cfsconfig': 'CfsConfig',
|
|
724
|
+
'inittimeout': 'InitTimeout',
|
|
725
|
+
// 注意:asyncRunEnable/traceEnable/autoDeployClsTopicIndex/autoCreateClsTopic
|
|
726
|
+
// 只能在 CreateFunction 时设置,UpdateFunctionConfiguration 不支持
|
|
727
|
+
// 注意:dnsCache 需要 'TRUE'/'FALSE' 字符串,在特殊处理阶段处理
|
|
728
|
+
'intranetconfig': 'IntranetConfig',
|
|
729
|
+
};
|
|
730
|
+
// 构建参数
|
|
585
731
|
const params = {
|
|
586
|
-
FunctionName: func.name,
|
|
587
732
|
Namespace: namespace,
|
|
588
|
-
|
|
733
|
+
FunctionName: func.name
|
|
589
734
|
};
|
|
590
|
-
|
|
591
|
-
|
|
735
|
+
// 白名单字段自动转换(大小写不敏感,统一输出 PascalCase)
|
|
736
|
+
for (const key of Object.keys(func)) {
|
|
737
|
+
const lowerKey = key.toLowerCase();
|
|
738
|
+
const pascalKey = UPDATE_CONFIG_FIELDS[lowerKey];
|
|
739
|
+
if (!pascalKey || func[key] === undefined)
|
|
740
|
+
continue;
|
|
741
|
+
params[pascalKey] = toPascalCaseKeys(func[key]);
|
|
742
|
+
}
|
|
743
|
+
// 特殊处理:安装依赖标志(支持 boolean | string)
|
|
744
|
+
if (func.installDependency !== undefined) {
|
|
745
|
+
params.InstallDependency = toBooleanString(func.installDependency);
|
|
746
|
+
}
|
|
747
|
+
// 特殊处理:L5 配置(支持 boolean | string)
|
|
748
|
+
if (func.l5 !== undefined) {
|
|
749
|
+
params.L5Enable = toBooleanString(func.l5);
|
|
750
|
+
}
|
|
751
|
+
// 特殊处理:DnsCache(支持 boolean | string,大小写不敏感)
|
|
752
|
+
// 注意:asyncRunEnable/traceEnable/autoDeployClsTopicIndex/autoCreateClsTopic
|
|
753
|
+
// 只能在 CreateFunction 时设置,UpdateFunctionConfiguration 不支持这些参数
|
|
754
|
+
const dnsCacheValue = getFieldIgnoreCase(func, 'dnsCache');
|
|
755
|
+
if (dnsCacheValue !== undefined) {
|
|
756
|
+
params.DnsCache = toBooleanString(dnsCacheValue);
|
|
592
757
|
}
|
|
593
|
-
//
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
//
|
|
599
|
-
func.
|
|
758
|
+
// 特殊处理:Publish - 是否同时发布新版本(支持 boolean | string,大小写不敏感)
|
|
759
|
+
const publishValue = getFieldIgnoreCase(func, 'publish');
|
|
760
|
+
if (publishValue !== undefined) {
|
|
761
|
+
params.Publish = toBooleanString(publishValue);
|
|
762
|
+
}
|
|
763
|
+
// 特殊处理:环境变量
|
|
764
|
+
if (func.envVariables && Object.keys(func.envVariables).length > 0) {
|
|
765
|
+
params.Environment = {
|
|
766
|
+
Variables: Object.keys(func.envVariables).map(key => ({
|
|
767
|
+
Key: key,
|
|
768
|
+
Value: func.envVariables[key]
|
|
769
|
+
}))
|
|
770
|
+
};
|
|
771
|
+
}
|
|
772
|
+
// 特殊处理:VPC 配置
|
|
600
773
|
if (((_a = func === null || func === void 0 ? void 0 : func.vpc) === null || _a === void 0 ? void 0 : _a.subnetId) !== undefined && ((_b = func === null || func === void 0 ? void 0 : func.vpc) === null || _b === void 0 ? void 0 : _b.vpcId) !== undefined) {
|
|
601
|
-
// VPC 网络
|
|
602
774
|
params.VpcConfig = {
|
|
603
|
-
SubnetId:
|
|
604
|
-
VpcId:
|
|
775
|
+
SubnetId: func.vpc.subnetId,
|
|
776
|
+
VpcId: func.vpc.vpcId
|
|
605
777
|
};
|
|
606
778
|
}
|
|
607
|
-
//
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
isNodeFunction(func.runtime) && (params.InstallDependency = 'TRUE');
|
|
611
|
-
// 是否安装依赖,选项可以覆盖
|
|
612
|
-
if (typeof func.installDependency !== 'undefined') {
|
|
613
|
-
params.InstallDependency = func.installDependency ? 'TRUE' : 'FALSE';
|
|
614
|
-
}
|
|
615
|
-
// 函数层
|
|
616
|
-
if ((_e = func === null || func === void 0 ? void 0 : func.layers) === null || _e === void 0 ? void 0 : _e.length) {
|
|
617
|
-
const transformLayers = func.layers.map(item => ({
|
|
779
|
+
// 特殊处理:函数层
|
|
780
|
+
if ((_c = func === null || func === void 0 ? void 0 : func.layers) === null || _c === void 0 ? void 0 : _c.length) {
|
|
781
|
+
params.Layers = func.layers.map(item => ({
|
|
618
782
|
LayerName: item.name,
|
|
619
783
|
LayerVersion: item.version
|
|
620
784
|
}));
|
|
621
|
-
params.Layers = transformLayers;
|
|
622
785
|
}
|
|
623
|
-
//
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
}
|
|
786
|
+
// 特殊处理:HTTP 函数多并发配置(大小写不敏感)
|
|
787
|
+
const instanceConcurrencyConfig = getFieldIgnoreCase(func, 'instanceConcurrencyConfig');
|
|
788
|
+
if (instanceConcurrencyConfig) {
|
|
789
|
+
const config = toPascalCaseKeys(instanceConcurrencyConfig);
|
|
790
|
+
// DynamicEnabled 需要特殊处理为 'TRUE'/'FALSE'
|
|
791
|
+
if (config.DynamicEnabled !== undefined) {
|
|
792
|
+
config.DynamicEnabled = toBooleanString(config.DynamicEnabled);
|
|
793
|
+
}
|
|
794
|
+
params.InstanceConcurrencyConfig = config;
|
|
631
795
|
}
|
|
632
|
-
//
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
796
|
+
// 特殊处理:HTTP 函数协议参数(WebSocket,大小写不敏感)
|
|
797
|
+
const protocolParams = getFieldIgnoreCase(func, 'protocolParams');
|
|
798
|
+
if (protocolParams) {
|
|
799
|
+
const wsParams = getFieldIgnoreCase(protocolParams, 'wsParams');
|
|
800
|
+
if (wsParams) {
|
|
801
|
+
params.ProtocolParams = {
|
|
802
|
+
WSParams: toPascalCaseKeys(wsParams)
|
|
803
|
+
};
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
// 特殊处理:忽略系统日志上报(Boolean 类型,直接传递,大小写不敏感)
|
|
807
|
+
const ignoreSysLogValue = getFieldIgnoreCase(func, 'ignoreSysLog');
|
|
808
|
+
if (ignoreSysLogValue !== undefined) {
|
|
809
|
+
params.IgnoreSysLog = ignoreSysLogValue;
|
|
638
810
|
}
|
|
639
811
|
try {
|
|
640
812
|
// 如果函数配置中包含触发器,则更新触发器
|
|
@@ -665,13 +837,38 @@ class FunctionService {
|
|
|
665
837
|
async updateFunctionCode(funcParam) {
|
|
666
838
|
const { func, functionRootPath, base64Code, codeSecret, functionPath, deployMode } = funcParam;
|
|
667
839
|
const funcName = func.name;
|
|
668
|
-
const {
|
|
840
|
+
const { namespace } = this.getFunctionConfig();
|
|
841
|
+
// 镜像部署:使用镜像配置更新函数代码
|
|
842
|
+
if (deployMode === 'image') {
|
|
843
|
+
const params = {
|
|
844
|
+
FunctionName: funcName,
|
|
845
|
+
Namespace: namespace,
|
|
846
|
+
Code: {
|
|
847
|
+
ImageConfig: buildImageConfig(func.imageConfig)
|
|
848
|
+
}
|
|
849
|
+
};
|
|
850
|
+
if (!params.Code.ImageConfig.ImageUri) {
|
|
851
|
+
throw new error_1.CloudBaseError('镜像部署需要配置 imageConfig.imageUri');
|
|
852
|
+
}
|
|
853
|
+
try {
|
|
854
|
+
// 等待函数状态正常
|
|
855
|
+
await this.waitFunctionActive(funcName, codeSecret);
|
|
856
|
+
return await this.scfService.request('UpdateFunctionCode', params);
|
|
857
|
+
}
|
|
858
|
+
catch (e) {
|
|
859
|
+
throw new error_1.CloudBaseError(`[${funcName}] 函数代码更新失败:${e.message}`, {
|
|
860
|
+
code: e.code,
|
|
861
|
+
requestId: e.requestId
|
|
862
|
+
});
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
// 代码部署:原有逻辑
|
|
669
866
|
let installDependency;
|
|
670
867
|
// Node 函数默认安装依赖
|
|
671
868
|
installDependency = isNodeFunction(func.runtime) ? 'TRUE' : 'FALSE';
|
|
672
|
-
//
|
|
673
|
-
if (
|
|
674
|
-
installDependency = func.installDependency
|
|
869
|
+
// 是否安装依赖,选项可以覆盖(支持 boolean | string)
|
|
870
|
+
if (func.installDependency !== undefined) {
|
|
871
|
+
installDependency = toBooleanString(func.installDependency);
|
|
675
872
|
}
|
|
676
873
|
const codeParams = await this.getCodeParams({
|
|
677
874
|
func,
|
|
@@ -682,7 +879,7 @@ class FunctionService {
|
|
|
682
879
|
}, installDependency);
|
|
683
880
|
const params = {
|
|
684
881
|
FunctionName: funcName,
|
|
685
|
-
|
|
882
|
+
Namespace: namespace,
|
|
686
883
|
Handler: func.handler || 'index.main',
|
|
687
884
|
InstallDependency: installDependency,
|
|
688
885
|
Code: codeParams
|
|
@@ -694,7 +891,7 @@ class FunctionService {
|
|
|
694
891
|
// 等待函数状态正常
|
|
695
892
|
await this.waitFunctionActive(funcName, codeSecret);
|
|
696
893
|
// 更新云函数代码
|
|
697
|
-
const res = await this.
|
|
894
|
+
const res = await this.scfService.request('UpdateFunctionCode', params);
|
|
698
895
|
if (installDependency && func.isWaitInstall === true) {
|
|
699
896
|
await this.waitFunctionActive(funcName, codeSecret);
|
|
700
897
|
}
|
|
@@ -1078,7 +1275,8 @@ class FunctionService {
|
|
|
1078
1275
|
if (Status === constant_1.SCF_STATUS.CREATE_FAILED) {
|
|
1079
1276
|
const errorDetails = (StatusReasons === null || StatusReasons === void 0 ? void 0 : StatusReasons.map(item => `[${item.ErrorCode}] ${item.ErrorMessage}`).join('\n')) || '';
|
|
1080
1277
|
const errorMsg = `云函数创建失败${StatusDesc ? `\n状态描述: ${StatusDesc}` : ''}${errorDetails ? `\n失败信息: ${errorDetails}` : ''}`;
|
|
1081
|
-
|
|
1278
|
+
// 注意:这里不传递 RequestId,因为这是 GetFunction 的 RequestId,不是导致失败的 CreateFunction/UpdateFunctionCode 的 RequestId
|
|
1279
|
+
throw new error_1.CloudBaseError(errorMsg);
|
|
1082
1280
|
}
|
|
1083
1281
|
// 函数状态正常
|
|
1084
1282
|
clearInterval(ticker);
|
|
@@ -1258,7 +1456,12 @@ class FunctionService {
|
|
|
1258
1456
|
// 清理临时文件
|
|
1259
1457
|
await packer.clean();
|
|
1260
1458
|
if (err) {
|
|
1261
|
-
|
|
1459
|
+
// 保留完整的错误信息(避免原始错误丢失)
|
|
1460
|
+
const errorMessage = err.message || err.error || String(err);
|
|
1461
|
+
const errorCode = err.code || err.statusCode || '';
|
|
1462
|
+
reject(new error_1.CloudBaseError(`COS 上传失败: ${errorMessage}${errorCode ? ` (${errorCode})` : ''}`, {
|
|
1463
|
+
code: errorCode
|
|
1464
|
+
}));
|
|
1262
1465
|
}
|
|
1263
1466
|
else {
|
|
1264
1467
|
resolve(data);
|
|
@@ -1311,7 +1514,16 @@ class FunctionService {
|
|
|
1311
1514
|
headers
|
|
1312
1515
|
});
|
|
1313
1516
|
if (!response.ok) {
|
|
1314
|
-
|
|
1517
|
+
// 尝试获取响应体中的错误信息
|
|
1518
|
+
let errorDetail = '';
|
|
1519
|
+
try {
|
|
1520
|
+
const responseText = await response.text();
|
|
1521
|
+
errorDetail = responseText ? ` - ${responseText}` : '';
|
|
1522
|
+
}
|
|
1523
|
+
catch (e) {
|
|
1524
|
+
// 忽略响应体解析错误
|
|
1525
|
+
}
|
|
1526
|
+
throw new error_1.CloudBaseError(`上传失败: ${response.status} ${response.statusText}${errorDetail}`);
|
|
1315
1527
|
}
|
|
1316
1528
|
// 清理临时文件
|
|
1317
1529
|
await packer.clean();
|
package/lib/storage/index.js
CHANGED
|
@@ -623,15 +623,25 @@ class StorageService {
|
|
|
623
623
|
* PRIVATE:仅创建者及管理员可读写
|
|
624
624
|
* ADMINWRITE:所有用户可读,仅管理员可写
|
|
625
625
|
* ADMINONLY:仅管理员可读写
|
|
626
|
-
*
|
|
626
|
+
* CUSTOM:自定义安全规则
|
|
627
|
+
* @returns {Promise<{ acl: AclType, rule?: IStorageAclRule }>}
|
|
627
628
|
*/
|
|
628
629
|
async getStorageAcl() {
|
|
629
630
|
const { bucket, env } = this.getStorageConfig();
|
|
630
|
-
const res = await this.tcbService.request('
|
|
631
|
+
const res = await this.tcbService.request('DescribeStorageSafeRule', {
|
|
631
632
|
EnvId: env,
|
|
632
633
|
Bucket: bucket
|
|
633
634
|
});
|
|
634
|
-
|
|
635
|
+
const result = { acl: res.AclTag };
|
|
636
|
+
if (res.AclTag === 'CUSTOM' && res.Rule) {
|
|
637
|
+
try {
|
|
638
|
+
result.rule = JSON.parse(res.Rule);
|
|
639
|
+
}
|
|
640
|
+
catch (_a) {
|
|
641
|
+
// Rule 可能不是 JSON 格式,忽略解析错误
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
return result;
|
|
635
645
|
}
|
|
636
646
|
/**
|
|
637
647
|
* 设置文件存储权限
|
|
@@ -639,20 +649,38 @@ class StorageService {
|
|
|
639
649
|
* PRIVATE:仅创建者及管理员可读写
|
|
640
650
|
* ADMINWRITE:所有用户可读,仅管理员可写
|
|
641
651
|
* ADMINONLY:仅管理员可读写
|
|
642
|
-
*
|
|
652
|
+
* CUSTOM:自定义安全规则(需要传入 rule 参数)
|
|
653
|
+
* @param {AclType} acl 权限类型
|
|
654
|
+
* @param {IStorageAclRule} [rule] 自定义安全规则,当 acl 为 CUSTOM 时必填
|
|
643
655
|
* @returns
|
|
656
|
+
* @example
|
|
657
|
+
* // 设置简易权限
|
|
658
|
+
* await storage.setStorageAcl('READONLY')
|
|
659
|
+
*
|
|
660
|
+
* // 设置自定义安全规则
|
|
661
|
+
* await storage.setStorageAcl('CUSTOM', {
|
|
662
|
+
* read: true,
|
|
663
|
+
* write: 'resource.openid == auth.uid'
|
|
664
|
+
* })
|
|
644
665
|
*/
|
|
645
|
-
async setStorageAcl(acl) {
|
|
646
|
-
const validAcl = ['READONLY', 'PRIVATE', 'ADMINWRITE', 'ADMINONLY'];
|
|
666
|
+
async setStorageAcl(acl, rule) {
|
|
667
|
+
const validAcl = ['READONLY', 'PRIVATE', 'ADMINWRITE', 'ADMINONLY', 'CUSTOM'];
|
|
647
668
|
if (!validAcl.includes(acl)) {
|
|
648
|
-
throw new error_1.CloudBaseError('
|
|
669
|
+
throw new error_1.CloudBaseError(`非法的权限类型: "${acl}", 有效值: ${validAcl.join(', ')}`);
|
|
670
|
+
}
|
|
671
|
+
if (acl === 'CUSTOM' && !rule) {
|
|
672
|
+
throw new error_1.CloudBaseError('使用 CUSTOM 权限类型时,必须提供 rule 参数');
|
|
649
673
|
}
|
|
650
674
|
const { bucket, env } = this.getStorageConfig();
|
|
651
|
-
|
|
675
|
+
const params = {
|
|
652
676
|
EnvId: env,
|
|
653
677
|
Bucket: bucket,
|
|
654
678
|
AclTag: acl
|
|
655
|
-
}
|
|
679
|
+
};
|
|
680
|
+
if (acl === 'CUSTOM' && rule) {
|
|
681
|
+
params.Rule = JSON.stringify(rule);
|
|
682
|
+
}
|
|
683
|
+
return this.tcbService.request('ModifyStorageSafeRule', params);
|
|
656
684
|
}
|
|
657
685
|
/**
|
|
658
686
|
* 遍历云端文件夹
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@ export interface IFunctionCode {
|
|
|
6
6
|
functionRootPath?: string;
|
|
7
7
|
base64Code?: string;
|
|
8
8
|
functionPath?: string;
|
|
9
|
-
deployMode?: 'cos' | 'zip';
|
|
9
|
+
deployMode?: 'cos' | 'zip' | 'image';
|
|
10
10
|
}
|
|
11
11
|
export interface ICreateFunctionParam {
|
|
12
12
|
func: ICloudFunction & {
|
|
@@ -17,7 +17,7 @@ export interface ICreateFunctionParam {
|
|
|
17
17
|
base64Code?: string;
|
|
18
18
|
functionPath?: string;
|
|
19
19
|
codeSecret?: string;
|
|
20
|
-
deployMode?: 'cos' | 'zip';
|
|
20
|
+
deployMode?: 'cos' | 'zip' | 'image';
|
|
21
21
|
}
|
|
22
22
|
export interface IUpdateFunctionCodeParam {
|
|
23
23
|
func: ICloudFunction;
|
|
@@ -25,7 +25,7 @@ export interface IUpdateFunctionCodeParam {
|
|
|
25
25
|
functionRootPath?: string;
|
|
26
26
|
base64Code?: string;
|
|
27
27
|
codeSecret?: string;
|
|
28
|
-
deployMode?: 'cos' | 'zip';
|
|
28
|
+
deployMode?: 'cos' | 'zip' | 'image';
|
|
29
29
|
}
|
|
30
30
|
export interface IUpdateFunctionIncrementalCodeParam {
|
|
31
31
|
func: ICloudFunction;
|
|
@@ -36,7 +36,7 @@ export interface IUpdateFunctionIncrementalCodeParam {
|
|
|
36
36
|
export interface ICreateFunctionRes {
|
|
37
37
|
triggerRes: IResponseInfo;
|
|
38
38
|
configRes: IResponseInfo;
|
|
39
|
-
codeRes
|
|
39
|
+
codeRes?: IResponseInfo;
|
|
40
40
|
}
|
|
41
41
|
export interface IFunctionLayerOptions {
|
|
42
42
|
contentPath?: string;
|
|
@@ -185,28 +185,40 @@ export interface IFunctionCode {
|
|
|
185
185
|
TempCosObjectName?: string;
|
|
186
186
|
ZipFile?: string;
|
|
187
187
|
CosTimestamp?: string;
|
|
188
|
+
ImageConfig?: {
|
|
189
|
+
ImageType?: string;
|
|
190
|
+
ImageUri?: string;
|
|
191
|
+
RegistryId?: string;
|
|
192
|
+
EntryPoint?: string;
|
|
193
|
+
Command?: string;
|
|
194
|
+
Args?: string;
|
|
195
|
+
ContainerImageAccelerate?: boolean;
|
|
196
|
+
ImagePort?: number;
|
|
197
|
+
CommandList?: string[];
|
|
198
|
+
ArgsList?: string[];
|
|
199
|
+
};
|
|
188
200
|
}
|
|
189
201
|
export interface ILayerVersionItem {
|
|
190
202
|
LayerName: string;
|
|
191
203
|
LayerVersion: number;
|
|
192
204
|
}
|
|
193
205
|
export interface IFunctionUpdateAttribute {
|
|
194
|
-
Code
|
|
195
|
-
Description
|
|
206
|
+
Code?: IFunctionCode;
|
|
207
|
+
Description?: string;
|
|
196
208
|
FunctionName: string;
|
|
197
|
-
MemorySize
|
|
198
|
-
Timeout
|
|
199
|
-
UseGpu
|
|
200
|
-
Namespace
|
|
201
|
-
Environment
|
|
209
|
+
MemorySize?: number;
|
|
210
|
+
Timeout?: number;
|
|
211
|
+
UseGpu?: 'FALSE' | 'TRUE';
|
|
212
|
+
Namespace?: string;
|
|
213
|
+
Environment?: {
|
|
202
214
|
Variables: IEnvVariable[];
|
|
203
215
|
};
|
|
204
|
-
VpcConfig
|
|
216
|
+
VpcConfig?: {
|
|
205
217
|
VpcId: string;
|
|
206
218
|
SubnetId: string;
|
|
207
219
|
};
|
|
208
220
|
InstallDependency?: 'FALSE' | 'TRUE';
|
|
209
|
-
PublicNetConfig
|
|
221
|
+
PublicNetConfig?: {
|
|
210
222
|
PublicNetStatus: string;
|
|
211
223
|
EipConfig: {
|
|
212
224
|
EipStatus: string;
|
|
@@ -216,4 +228,20 @@ export interface IFunctionUpdateAttribute {
|
|
|
216
228
|
Layers?: ILayerVersionItem[];
|
|
217
229
|
ClsLogsetId?: string;
|
|
218
230
|
ClsTopicId?: string;
|
|
231
|
+
Runtime?: string;
|
|
232
|
+
Handler?: string;
|
|
233
|
+
Role?: string;
|
|
234
|
+
L5Enable?: string | null;
|
|
235
|
+
CodeSecret?: string;
|
|
236
|
+
Type?: string;
|
|
237
|
+
ProtocolType?: string;
|
|
238
|
+
ProtocolParams?: {
|
|
239
|
+
WSParams?: {
|
|
240
|
+
IdleTimeOut?: number;
|
|
241
|
+
};
|
|
242
|
+
};
|
|
243
|
+
InstanceConcurrencyConfig?: {
|
|
244
|
+
DynamicEnabled?: 'FALSE' | 'TRUE';
|
|
245
|
+
MaxConcurrency?: number;
|
|
246
|
+
};
|
|
219
247
|
}
|
|
@@ -12,8 +12,15 @@ export interface ICloudFunctionConfig {
|
|
|
12
12
|
envVariables?: Record<string, string | number | boolean>;
|
|
13
13
|
runtime?: string;
|
|
14
14
|
vpc?: IFunctionVPC;
|
|
15
|
-
installDependency?: boolean;
|
|
16
|
-
l5?: boolean;
|
|
15
|
+
installDependency?: boolean | 'TRUE' | 'FALSE';
|
|
16
|
+
l5?: boolean | 'TRUE' | 'FALSE';
|
|
17
|
+
asyncRunEnable?: boolean | 'TRUE' | 'FALSE';
|
|
18
|
+
traceEnable?: boolean | 'TRUE' | 'FALSE';
|
|
19
|
+
autoDeployClsTopicIndex?: boolean | 'TRUE' | 'FALSE';
|
|
20
|
+
autoCreateClsTopic?: boolean | 'TRUE' | 'FALSE';
|
|
21
|
+
dnsCache?: boolean | 'TRUE' | 'FALSE';
|
|
22
|
+
publish?: boolean | 'TRUE' | 'FALSE';
|
|
23
|
+
ignoreSysLog?: boolean;
|
|
17
24
|
memorySize?: number;
|
|
18
25
|
role?: string;
|
|
19
26
|
}
|
|
@@ -21,6 +28,18 @@ export interface LayerVersionSimple {
|
|
|
21
28
|
LayerName: string;
|
|
22
29
|
LayerVersion: number;
|
|
23
30
|
}
|
|
31
|
+
export interface IFunctionImageConfig {
|
|
32
|
+
imageType: 'enterprise' | 'personal';
|
|
33
|
+
imageUri: string;
|
|
34
|
+
registryId?: string;
|
|
35
|
+
entryPoint?: string;
|
|
36
|
+
command?: string;
|
|
37
|
+
args?: string;
|
|
38
|
+
containerImageAccelerate?: boolean;
|
|
39
|
+
imagePort?: number;
|
|
40
|
+
commandList?: string[];
|
|
41
|
+
argsList?: string[];
|
|
42
|
+
}
|
|
24
43
|
export interface ICloudFunction extends ICloudFunctionConfig {
|
|
25
44
|
name: string;
|
|
26
45
|
description?: string;
|
|
@@ -32,8 +51,13 @@ export interface ICloudFunction extends ICloudFunctionConfig {
|
|
|
32
51
|
};
|
|
33
52
|
};
|
|
34
53
|
instanceConcurrencyConfig?: {
|
|
35
|
-
dynamicEnabled?: 'FALSE';
|
|
54
|
+
dynamicEnabled?: boolean | 'TRUE' | 'FALSE';
|
|
36
55
|
maxConcurrency?: number;
|
|
56
|
+
instanceIsolationEnabled?: boolean | 'TRUE' | 'FALSE';
|
|
57
|
+
type?: string;
|
|
58
|
+
mixNodeConfig?: any;
|
|
59
|
+
sessionConfig?: any;
|
|
60
|
+
[key: string]: any;
|
|
37
61
|
};
|
|
38
62
|
handler?: string;
|
|
39
63
|
codeSecret?: string;
|
|
@@ -44,6 +68,7 @@ export interface ICloudFunction extends ICloudFunctionConfig {
|
|
|
44
68
|
version: number;
|
|
45
69
|
}[];
|
|
46
70
|
triggers?: ICloudFunctionTrigger[];
|
|
71
|
+
imageConfig?: IFunctionImageConfig;
|
|
47
72
|
}
|
|
48
73
|
export interface ICloudFunctionV2 {
|
|
49
74
|
name: string;
|
package/types/storage/index.d.ts
CHANGED
|
@@ -59,7 +59,13 @@ export interface IGetBucketOpions {
|
|
|
59
59
|
marker?: string;
|
|
60
60
|
maxKeys?: number;
|
|
61
61
|
}
|
|
62
|
-
export type AclType = 'READONLY' | 'PRIVATE' | 'ADMINWRITE' | 'ADMINONLY';
|
|
62
|
+
export type AclType = 'READONLY' | 'PRIVATE' | 'ADMINWRITE' | 'ADMINONLY' | 'CUSTOM';
|
|
63
|
+
export interface IStorageAclRule {
|
|
64
|
+
/** 读权限规则,true 表示所有用户可读,字符串表示自定义规则表达式 */
|
|
65
|
+
read: boolean | string;
|
|
66
|
+
/** 写权限规则,true 表示所有用户可写,字符串表示自定义规则表达式 */
|
|
67
|
+
write: boolean | string;
|
|
68
|
+
}
|
|
63
69
|
type OnProgress = (progressData: IProgressData) => void;
|
|
64
70
|
type OnFileFinish = (error: Error, res: any, fileData: any) => void;
|
|
65
71
|
export declare class StorageService {
|
|
@@ -220,19 +226,34 @@ export declare class StorageService {
|
|
|
220
226
|
* PRIVATE:仅创建者及管理员可读写
|
|
221
227
|
* ADMINWRITE:所有用户可读,仅管理员可写
|
|
222
228
|
* ADMINONLY:仅管理员可读写
|
|
223
|
-
*
|
|
229
|
+
* CUSTOM:自定义安全规则
|
|
230
|
+
* @returns {Promise<{ acl: AclType, rule?: IStorageAclRule }>}
|
|
224
231
|
*/
|
|
225
|
-
getStorageAcl(): Promise<
|
|
232
|
+
getStorageAcl(): Promise<{
|
|
233
|
+
acl: AclType;
|
|
234
|
+
rule?: IStorageAclRule;
|
|
235
|
+
}>;
|
|
226
236
|
/**
|
|
227
237
|
* 设置文件存储权限
|
|
228
238
|
* READONLY:所有用户可读,仅创建者和管理员可写
|
|
229
239
|
* PRIVATE:仅创建者及管理员可读写
|
|
230
240
|
* ADMINWRITE:所有用户可读,仅管理员可写
|
|
231
241
|
* ADMINONLY:仅管理员可读写
|
|
232
|
-
*
|
|
242
|
+
* CUSTOM:自定义安全规则(需要传入 rule 参数)
|
|
243
|
+
* @param {AclType} acl 权限类型
|
|
244
|
+
* @param {IStorageAclRule} [rule] 自定义安全规则,当 acl 为 CUSTOM 时必填
|
|
233
245
|
* @returns
|
|
234
|
-
|
|
235
|
-
|
|
246
|
+
* @example
|
|
247
|
+
* // 设置简易权限
|
|
248
|
+
* await storage.setStorageAcl('READONLY')
|
|
249
|
+
*
|
|
250
|
+
* // 设置自定义安全规则
|
|
251
|
+
* await storage.setStorageAcl('CUSTOM', {
|
|
252
|
+
* read: true,
|
|
253
|
+
* write: 'resource.openid == auth.uid'
|
|
254
|
+
* })
|
|
255
|
+
*/
|
|
256
|
+
setStorageAcl(acl: AclType, rule?: IStorageAclRule): Promise<IResponseInfo>;
|
|
236
257
|
/**
|
|
237
258
|
* 遍历云端文件夹
|
|
238
259
|
* @param {string} prefix
|