@cloudbase/manager-node 3.11.0 → 3.12.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/function/index.js +136 -0
- package/lib/storage/index.js +76 -25
- package/package.json +1 -1
- package/src/function/index.ts +237 -0
- package/src/storage/index.ts +93 -34
- package/types/function/index.d.ts +138 -0
- package/types/storage/index.d.ts +15 -0
package/lib/function/index.js
CHANGED
|
@@ -628,6 +628,121 @@ class FunctionService {
|
|
|
628
628
|
LayerVersion: version
|
|
629
629
|
});
|
|
630
630
|
}
|
|
631
|
+
/**
|
|
632
|
+
* 设置预置并发
|
|
633
|
+
* @private
|
|
634
|
+
* @param {IProvisionedConcurrencyConfig} concurrencyConfig
|
|
635
|
+
* @returns
|
|
636
|
+
* @memberof FunctionService
|
|
637
|
+
*/
|
|
638
|
+
async setProvisionedConcurrencyConfig(concurrencyConfig) {
|
|
639
|
+
const { namespace } = this.getFunctionConfig();
|
|
640
|
+
const { functionName: FunctionName, qualifier: Qualifier, versionProvisionedConcurrencyNum: VersionProvisionedConcurrencyNum } = concurrencyConfig;
|
|
641
|
+
return this.scfService.request('PutProvisionedConcurrencyConfig', {
|
|
642
|
+
FunctionName,
|
|
643
|
+
Qualifier,
|
|
644
|
+
VersionProvisionedConcurrencyNum,
|
|
645
|
+
Namespace: namespace
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* 获取函数预置并发详情
|
|
650
|
+
* @private
|
|
651
|
+
* @param {IGetProvisionedConcurrencyConfig} concurrencyConfig
|
|
652
|
+
* @returns {Promise<IGetProvisionedConcurrencyRes>}
|
|
653
|
+
* @memberof FunctionService
|
|
654
|
+
*/
|
|
655
|
+
async getProvisionedConcurrencyConfig(concurrencyConfig) {
|
|
656
|
+
const { namespace } = this.getFunctionConfig();
|
|
657
|
+
const { functionName: FunctionName, qualifier: Qualifier } = concurrencyConfig;
|
|
658
|
+
return this.scfService.request('GetProvisionedConcurrencyConfig', {
|
|
659
|
+
FunctionName,
|
|
660
|
+
Qualifier,
|
|
661
|
+
Namespace: namespace
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* 删除预置并发
|
|
666
|
+
* @private
|
|
667
|
+
* @param {IGetProvisionedConcurrencyConfig} concurrencyConfig
|
|
668
|
+
* @returns {Promise<IResponseInfo>}
|
|
669
|
+
* @memberof FunctionService
|
|
670
|
+
*/
|
|
671
|
+
async deleteProvisionedConcurrencyConfig(concurrencyConfig) {
|
|
672
|
+
const { namespace } = this.getFunctionConfig();
|
|
673
|
+
const { functionName: FunctionName, qualifier: Qualifier } = concurrencyConfig;
|
|
674
|
+
return this.scfService.request('DeleteProvisionedConcurrencyConfig', {
|
|
675
|
+
FunctionName,
|
|
676
|
+
Qualifier,
|
|
677
|
+
Namespace: namespace
|
|
678
|
+
});
|
|
679
|
+
}
|
|
680
|
+
/**
|
|
681
|
+
* 发布新版本
|
|
682
|
+
* @param {IPublishVersionParams} publishParams
|
|
683
|
+
* @returns {Promise<IPublishVersionRes>}
|
|
684
|
+
* @memberof FunctionService
|
|
685
|
+
*/
|
|
686
|
+
async publishVersion(publishParams) {
|
|
687
|
+
const { namespace } = this.getFunctionConfig();
|
|
688
|
+
const { functionName: FunctionName, description: Description } = publishParams;
|
|
689
|
+
return this.scfService.request('PublishVersion', {
|
|
690
|
+
FunctionName,
|
|
691
|
+
Description,
|
|
692
|
+
Namespace: namespace
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
/**
|
|
696
|
+
* 查询函数版本详情
|
|
697
|
+
* @param {IListFunctionVersionParams} listVersionParams
|
|
698
|
+
* @returns {Promise<IFunctionVersionsRes>}
|
|
699
|
+
* @memberof FunctionService
|
|
700
|
+
*/
|
|
701
|
+
async listVersionByFunction(listVersionParams) {
|
|
702
|
+
const { namespace } = this.getFunctionConfig();
|
|
703
|
+
const { functionName: FunctionName, offset: Offset, limit: Limit, order: Order, orderBy: OrderBy } = listVersionParams;
|
|
704
|
+
return this.scfService.request('ListVersionByFunction', {
|
|
705
|
+
FunctionName,
|
|
706
|
+
Namespace: namespace,
|
|
707
|
+
Offset,
|
|
708
|
+
Limit,
|
|
709
|
+
Order,
|
|
710
|
+
OrderBy
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
*
|
|
715
|
+
* @param {IUpdateFunctionAliasConfig} updateVersionConfigParams
|
|
716
|
+
* @returns {Promise<IResponseInfo>}
|
|
717
|
+
* @memberof FunctionService
|
|
718
|
+
*/
|
|
719
|
+
async updateFunctionAliasConfig(updateVersionConfigParams) {
|
|
720
|
+
const { namespace } = this.getFunctionConfig();
|
|
721
|
+
const { functionName: FunctionName, name: Name, functionVersion: FunctionVersion, routingConfig: RoutingConfig, description: Description } = updateVersionConfigParams;
|
|
722
|
+
return this.scfService.request('UpdateAlias', {
|
|
723
|
+
FunctionName,
|
|
724
|
+
Name,
|
|
725
|
+
Namespace: namespace,
|
|
726
|
+
FunctionVersion,
|
|
727
|
+
RoutingConfig,
|
|
728
|
+
Description
|
|
729
|
+
});
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* 查询函数别名详情
|
|
733
|
+
* @param {IGetFunctionAlias} params
|
|
734
|
+
* @returns {Promise<IGetFunctionAliasRes>}
|
|
735
|
+
* @memberof FunctionService
|
|
736
|
+
*/
|
|
737
|
+
async getFunctionAlias(params) {
|
|
738
|
+
const { namespace } = this.getFunctionConfig();
|
|
739
|
+
const { functionName: FunctionName, name: Name } = params;
|
|
740
|
+
return this.scfService.request('GetAlias', {
|
|
741
|
+
FunctionName,
|
|
742
|
+
Name,
|
|
743
|
+
Namespace: namespace
|
|
744
|
+
});
|
|
745
|
+
}
|
|
631
746
|
async createAccessPath(name, path) {
|
|
632
747
|
const access = this.environment.getAccessService();
|
|
633
748
|
try {
|
|
@@ -856,6 +971,27 @@ __decorate([
|
|
|
856
971
|
__decorate([
|
|
857
972
|
utils_1.preLazy()
|
|
858
973
|
], FunctionService.prototype, "getLayerVersion", null);
|
|
974
|
+
__decorate([
|
|
975
|
+
utils_1.preLazy()
|
|
976
|
+
], FunctionService.prototype, "setProvisionedConcurrencyConfig", null);
|
|
977
|
+
__decorate([
|
|
978
|
+
utils_1.preLazy()
|
|
979
|
+
], FunctionService.prototype, "getProvisionedConcurrencyConfig", null);
|
|
980
|
+
__decorate([
|
|
981
|
+
utils_1.preLazy()
|
|
982
|
+
], FunctionService.prototype, "deleteProvisionedConcurrencyConfig", null);
|
|
983
|
+
__decorate([
|
|
984
|
+
utils_1.preLazy()
|
|
985
|
+
], FunctionService.prototype, "publishVersion", null);
|
|
986
|
+
__decorate([
|
|
987
|
+
utils_1.preLazy()
|
|
988
|
+
], FunctionService.prototype, "listVersionByFunction", null);
|
|
989
|
+
__decorate([
|
|
990
|
+
utils_1.preLazy()
|
|
991
|
+
], FunctionService.prototype, "updateFunctionAliasConfig", null);
|
|
992
|
+
__decorate([
|
|
993
|
+
utils_1.preLazy()
|
|
994
|
+
], FunctionService.prototype, "getFunctionAlias", null);
|
|
859
995
|
__decorate([
|
|
860
996
|
utils_1.preLazy()
|
|
861
997
|
], FunctionService.prototype, "createAccessPath", null);
|
package/lib/storage/index.js
CHANGED
|
@@ -382,27 +382,32 @@ class StorageService {
|
|
|
382
382
|
* @returns {Promise<(NodeJS.ReadableStream | string)[]>}
|
|
383
383
|
*/
|
|
384
384
|
async downloadDirectory(options) {
|
|
385
|
-
const { cloudPath, localPath } = options;
|
|
385
|
+
const { cloudPath, localPath, parallel = 20 } = options;
|
|
386
386
|
const resolveLocalPath = path_1.default.resolve(localPath);
|
|
387
387
|
utils_1.checkFullAccess(resolveLocalPath, true);
|
|
388
388
|
const cloudDirectoryKey = this.getCloudKey(cloudPath);
|
|
389
389
|
const files = await this.walkCloudDir(cloudDirectoryKey);
|
|
390
|
-
const promises = files.map(async (
|
|
391
|
-
|
|
392
|
-
// 空路径和文件夹跳过
|
|
393
|
-
if (!fileRelativePath || /\/$/g.test(fileRelativePath)) {
|
|
394
|
-
return;
|
|
395
|
-
}
|
|
396
|
-
const localFilePath = path_1.default.join(resolveLocalPath, fileRelativePath);
|
|
397
|
-
// 创建文件的父文件夹
|
|
398
|
-
const fileDir = path_1.default.dirname(localFilePath);
|
|
399
|
-
await make_dir_1.default(fileDir);
|
|
400
|
-
return this.downloadFile({
|
|
401
|
-
cloudPath: file.Key,
|
|
402
|
-
localPath: localFilePath
|
|
403
|
-
});
|
|
390
|
+
const promises = files.map(file => async () => {
|
|
391
|
+
return this.downloadWithFilePath({ file, cloudDirectoryKey, resolveLocalPath });
|
|
404
392
|
});
|
|
405
|
-
|
|
393
|
+
const asyncTaskController = new parallel_1.AsyncTaskParallelController(parallel, 50);
|
|
394
|
+
asyncTaskController.loadTasks(promises);
|
|
395
|
+
let res = await asyncTaskController.run();
|
|
396
|
+
const errorIndexArr = [];
|
|
397
|
+
res.map((item, index) => /Error/gi.test(Object.prototype.toString.call(item)) && errorIndexArr.push(index));
|
|
398
|
+
// 重试逻辑
|
|
399
|
+
if (errorIndexArr.length) {
|
|
400
|
+
const errorFiles = errorIndexArr.map(errorIndex => files[errorIndex]);
|
|
401
|
+
asyncTaskController.loadTasks(errorFiles.map(file => async () => {
|
|
402
|
+
return this.downloadWithFilePath({ file, cloudDirectoryKey, resolveLocalPath });
|
|
403
|
+
}));
|
|
404
|
+
res = await asyncTaskController.run();
|
|
405
|
+
}
|
|
406
|
+
const errorResultArr = this.determineDownLoadResultIsError(res);
|
|
407
|
+
if (errorResultArr.length) {
|
|
408
|
+
throw errorResultArr[0];
|
|
409
|
+
}
|
|
410
|
+
return res;
|
|
406
411
|
}
|
|
407
412
|
/**
|
|
408
413
|
* 列出文件夹下的文件
|
|
@@ -889,27 +894,73 @@ class StorageService {
|
|
|
889
894
|
async uploadFilesWithRetry({ uploadFiles, options, times, interval, failedFiles }) {
|
|
890
895
|
const { files, onFileFinish } = options;
|
|
891
896
|
const tempFailedFiles = [];
|
|
897
|
+
let curError = null;
|
|
892
898
|
const res = await uploadFiles(Object.assign(Object.assign({}, options), { files: failedFiles.length
|
|
893
899
|
? files.filter(file => failedFiles.includes(file.Key))
|
|
894
900
|
: files, onFileFinish: (...args) => {
|
|
895
901
|
const error = args[0];
|
|
896
902
|
const fileInfo = args[2];
|
|
897
903
|
if (error) {
|
|
904
|
+
curError = error;
|
|
898
905
|
tempFailedFiles.push(fileInfo.Key);
|
|
899
906
|
}
|
|
900
907
|
onFileFinish === null || onFileFinish === void 0 ? void 0 : onFileFinish.apply(null, args);
|
|
901
908
|
} }));
|
|
902
|
-
if (!
|
|
909
|
+
// if (!tempFailedFiles?.length || times <= 0) return res
|
|
910
|
+
if (!(tempFailedFiles === null || tempFailedFiles === void 0 ? void 0 : tempFailedFiles.length)) {
|
|
903
911
|
return res;
|
|
904
|
-
if (times > 0) {
|
|
905
|
-
setTimeout(() => this.uploadFilesWithRetry({
|
|
906
|
-
uploadFiles,
|
|
907
|
-
options,
|
|
908
|
-
times: times - 1,
|
|
909
|
-
interval,
|
|
910
|
-
failedFiles: tempFailedFiles
|
|
911
|
-
}), interval);
|
|
912
912
|
}
|
|
913
|
+
else {
|
|
914
|
+
if (times > 0) {
|
|
915
|
+
return await new Promise((resolve, reject) => {
|
|
916
|
+
setTimeout(() => this.uploadFilesWithRetry({
|
|
917
|
+
uploadFiles,
|
|
918
|
+
options,
|
|
919
|
+
times: times - 1,
|
|
920
|
+
interval,
|
|
921
|
+
failedFiles: tempFailedFiles
|
|
922
|
+
}).then(res => resolve(res))
|
|
923
|
+
.catch(err => reject(err)), interval);
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
else {
|
|
927
|
+
if (curError) {
|
|
928
|
+
throw curError;
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
/**
|
|
934
|
+
* 拼接路径下载单文件
|
|
935
|
+
* @param file
|
|
936
|
+
* @param cloudDirectoryKey
|
|
937
|
+
* @param resolveLocalPath
|
|
938
|
+
* @returns
|
|
939
|
+
*/
|
|
940
|
+
async downloadWithFilePath({ file, cloudDirectoryKey, resolveLocalPath }) {
|
|
941
|
+
const fileRelativePath = file.Key.replace(cloudDirectoryKey, '');
|
|
942
|
+
// 空路径和文件夹跳过
|
|
943
|
+
if (!fileRelativePath || /\/$/g.test(fileRelativePath)) {
|
|
944
|
+
return;
|
|
945
|
+
}
|
|
946
|
+
const localFilePath = path_1.default.join(resolveLocalPath, fileRelativePath);
|
|
947
|
+
// 创建文件的父文件夹
|
|
948
|
+
const fileDir = path_1.default.dirname(localFilePath);
|
|
949
|
+
await make_dir_1.default(fileDir);
|
|
950
|
+
return this.downloadFile({
|
|
951
|
+
cloudPath: file.Key,
|
|
952
|
+
localPath: localFilePath
|
|
953
|
+
});
|
|
954
|
+
}
|
|
955
|
+
/**
|
|
956
|
+
* 根据下载结果返回错误列表
|
|
957
|
+
* @param res
|
|
958
|
+
* @returns
|
|
959
|
+
*/
|
|
960
|
+
determineDownLoadResultIsError(res) {
|
|
961
|
+
const resultErrorArr = [];
|
|
962
|
+
res.map(item => /Error/gi.test(Object.prototype.toString.call(item)) && resultErrorArr.push(item));
|
|
963
|
+
return resultErrorArr;
|
|
913
964
|
}
|
|
914
965
|
}
|
|
915
966
|
__decorate([
|
package/package.json
CHANGED
package/src/function/index.ts
CHANGED
|
@@ -126,6 +126,107 @@ export interface IGetLayerVersionRes extends IResponseInfo {
|
|
|
126
126
|
Status: string // 层的具体版本当前状态
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
export interface ISetProvisionedConcurrencyConfig {
|
|
130
|
+
functionName: string
|
|
131
|
+
qualifier: string
|
|
132
|
+
versionProvisionedConcurrencyNum: number
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export interface IGetProvisionedConcurrencyConfig {
|
|
136
|
+
functionName: string
|
|
137
|
+
qualifier?: string
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export interface IVersionProvisionedConcurrencyInfo {
|
|
141
|
+
AllocatedProvisionedConcurrencyNum: number // 设置的预置并发数。
|
|
142
|
+
AvailableProvisionedConcurrencyNum: number // 当前已完成预置的并发数。
|
|
143
|
+
Status: string // 预置任务状态,Done表示已完成,InProgress表示进行中,Failed表示部分或全部失败。
|
|
144
|
+
StatusReason: string // 对预置任务状态Status的说明。
|
|
145
|
+
Qualifier: string // 版本号
|
|
146
|
+
}
|
|
147
|
+
export interface IGetProvisionedConcurrencyRes extends IResponseInfo {
|
|
148
|
+
UnallocatedConcurrencyNum: number
|
|
149
|
+
Allocated: IVersionProvisionedConcurrencyInfo[]
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export interface IPublishVersionParams {
|
|
153
|
+
functionName: string
|
|
154
|
+
description?: string
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export interface IPublishVersionRes extends IResponseInfo {
|
|
158
|
+
FunctionVersion: string
|
|
159
|
+
CodeSize: number
|
|
160
|
+
MemorySize: number
|
|
161
|
+
Description: string
|
|
162
|
+
Handler: string
|
|
163
|
+
Timeout: number
|
|
164
|
+
Runtime: string
|
|
165
|
+
Namespace: string
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
export interface IListFunctionVersionParams {
|
|
170
|
+
functionName: string
|
|
171
|
+
offset?: number
|
|
172
|
+
limit?: number
|
|
173
|
+
order?: string
|
|
174
|
+
orderBy?: string
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export interface IFunctionVersion {
|
|
178
|
+
Version: string
|
|
179
|
+
Description: string
|
|
180
|
+
AddTime: string
|
|
181
|
+
ModTime: string
|
|
182
|
+
Status: string //
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export interface IFunctionVersionsRes extends IResponseInfo {
|
|
186
|
+
FunctionVersion: string[]
|
|
187
|
+
Versions: IFunctionVersion[]
|
|
188
|
+
TotalCount: number
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export interface IVersionMatch {
|
|
192
|
+
Version: string // 函数版本名称
|
|
193
|
+
Key: string // 匹配规则的key,调用时通过传key来匹配规则路由到指定版本 header方式:key填写"invoke.headers.User",并在 invoke 调用函数时传参 RoutingKey:{"User":"value"}规则匹配调用
|
|
194
|
+
Method: string // 匹配方式。取值范围:range:范围匹配 exact:字符串精确匹配
|
|
195
|
+
Expression: string //
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export interface IVersionWeight {
|
|
199
|
+
Version: string
|
|
200
|
+
Weight: number
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export interface IRoutingConfig {
|
|
204
|
+
AdditionalVersionWeights?: IVersionWeight[]
|
|
205
|
+
AddtionVersionMatchs?: IVersionMatch[]
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export interface IUpdateFunctionAliasConfig {
|
|
209
|
+
functionName: string // 函数名
|
|
210
|
+
name: string // 函数别名 如$DEFAULT
|
|
211
|
+
functionVersion: string // 函数版本
|
|
212
|
+
description?: string // 别名描述
|
|
213
|
+
routingConfig?: IRoutingConfig
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export interface IGetFunctionAlias {
|
|
217
|
+
functionName: string // 函数名称
|
|
218
|
+
name: string // 别名
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export interface IGetFunctionAliasRes extends IResponseInfo {
|
|
222
|
+
FunctionVersion: string
|
|
223
|
+
Name: string
|
|
224
|
+
RoutingConfig: IRoutingConfig
|
|
225
|
+
Description: string
|
|
226
|
+
AddTime: string
|
|
227
|
+
ModTime: string
|
|
228
|
+
}
|
|
229
|
+
|
|
129
230
|
// 是否为 Node 函数
|
|
130
231
|
function isNodeFunction(runtime: string) {
|
|
131
232
|
// 不严格限制
|
|
@@ -913,6 +1014,142 @@ export class FunctionService {
|
|
|
913
1014
|
})
|
|
914
1015
|
}
|
|
915
1016
|
|
|
1017
|
+
/**
|
|
1018
|
+
* 设置预置并发
|
|
1019
|
+
* @private
|
|
1020
|
+
* @param {IProvisionedConcurrencyConfig} concurrencyConfig
|
|
1021
|
+
* @returns
|
|
1022
|
+
* @memberof FunctionService
|
|
1023
|
+
*/
|
|
1024
|
+
@preLazy()
|
|
1025
|
+
public async setProvisionedConcurrencyConfig(concurrencyConfig: ISetProvisionedConcurrencyConfig): Promise<IResponseInfo> {
|
|
1026
|
+
const { namespace } = this.getFunctionConfig()
|
|
1027
|
+
const { functionName: FunctionName, qualifier: Qualifier, versionProvisionedConcurrencyNum: VersionProvisionedConcurrencyNum } = concurrencyConfig
|
|
1028
|
+
|
|
1029
|
+
return this.scfService.request('PutProvisionedConcurrencyConfig', {
|
|
1030
|
+
FunctionName,
|
|
1031
|
+
Qualifier,
|
|
1032
|
+
VersionProvisionedConcurrencyNum,
|
|
1033
|
+
Namespace: namespace
|
|
1034
|
+
})
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
/**
|
|
1038
|
+
* 获取函数预置并发详情
|
|
1039
|
+
* @private
|
|
1040
|
+
* @param {IGetProvisionedConcurrencyConfig} concurrencyConfig
|
|
1041
|
+
* @returns {Promise<IGetProvisionedConcurrencyRes>}
|
|
1042
|
+
* @memberof FunctionService
|
|
1043
|
+
*/
|
|
1044
|
+
@preLazy()
|
|
1045
|
+
public async getProvisionedConcurrencyConfig(concurrencyConfig: IGetProvisionedConcurrencyConfig): Promise<IGetProvisionedConcurrencyRes> {
|
|
1046
|
+
const { namespace } = this.getFunctionConfig()
|
|
1047
|
+
const { functionName: FunctionName, qualifier: Qualifier } = concurrencyConfig
|
|
1048
|
+
|
|
1049
|
+
return this.scfService.request('GetProvisionedConcurrencyConfig', {
|
|
1050
|
+
FunctionName,
|
|
1051
|
+
Qualifier,
|
|
1052
|
+
Namespace: namespace
|
|
1053
|
+
})
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
/**
|
|
1057
|
+
* 删除预置并发
|
|
1058
|
+
* @private
|
|
1059
|
+
* @param {IGetProvisionedConcurrencyConfig} concurrencyConfig
|
|
1060
|
+
* @returns {Promise<IResponseInfo>}
|
|
1061
|
+
* @memberof FunctionService
|
|
1062
|
+
*/
|
|
1063
|
+
@preLazy()
|
|
1064
|
+
public async deleteProvisionedConcurrencyConfig(concurrencyConfig: IGetProvisionedConcurrencyConfig): Promise<IResponseInfo> {
|
|
1065
|
+
const { namespace } = this.getFunctionConfig()
|
|
1066
|
+
const { functionName: FunctionName, qualifier: Qualifier } = concurrencyConfig
|
|
1067
|
+
|
|
1068
|
+
return this.scfService.request('DeleteProvisionedConcurrencyConfig', {
|
|
1069
|
+
FunctionName,
|
|
1070
|
+
Qualifier,
|
|
1071
|
+
Namespace: namespace
|
|
1072
|
+
})
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
/**
|
|
1076
|
+
* 发布新版本
|
|
1077
|
+
* @param {IPublishVersionParams} publishParams
|
|
1078
|
+
* @returns {Promise<IPublishVersionRes>}
|
|
1079
|
+
* @memberof FunctionService
|
|
1080
|
+
*/
|
|
1081
|
+
@preLazy()
|
|
1082
|
+
public async publishVersion(publishParams: IPublishVersionParams): Promise<IPublishVersionRes> {
|
|
1083
|
+
const { namespace } = this.getFunctionConfig()
|
|
1084
|
+
const { functionName: FunctionName, description: Description } = publishParams
|
|
1085
|
+
|
|
1086
|
+
return this.scfService.request('PublishVersion', {
|
|
1087
|
+
FunctionName,
|
|
1088
|
+
Description,
|
|
1089
|
+
Namespace: namespace
|
|
1090
|
+
})
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
/**
|
|
1094
|
+
* 查询函数版本详情
|
|
1095
|
+
* @param {IListFunctionVersionParams} listVersionParams
|
|
1096
|
+
* @returns {Promise<IFunctionVersionsRes>}
|
|
1097
|
+
* @memberof FunctionService
|
|
1098
|
+
*/
|
|
1099
|
+
@preLazy()
|
|
1100
|
+
public async listVersionByFunction(listVersionParams: IListFunctionVersionParams): Promise<IFunctionVersionsRes> {
|
|
1101
|
+
const { namespace } = this.getFunctionConfig()
|
|
1102
|
+
const { functionName: FunctionName, offset: Offset, limit: Limit, order: Order, orderBy: OrderBy } = listVersionParams
|
|
1103
|
+
|
|
1104
|
+
return this.scfService.request('ListVersionByFunction', {
|
|
1105
|
+
FunctionName,
|
|
1106
|
+
Namespace: namespace,
|
|
1107
|
+
Offset,
|
|
1108
|
+
Limit,
|
|
1109
|
+
Order,
|
|
1110
|
+
OrderBy
|
|
1111
|
+
})
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
/**
|
|
1115
|
+
*
|
|
1116
|
+
* @param {IUpdateFunctionAliasConfig} updateVersionConfigParams
|
|
1117
|
+
* @returns {Promise<IResponseInfo>}
|
|
1118
|
+
* @memberof FunctionService
|
|
1119
|
+
*/
|
|
1120
|
+
@preLazy()
|
|
1121
|
+
public async updateFunctionAliasConfig(updateVersionConfigParams: IUpdateFunctionAliasConfig): Promise<IResponseInfo> {
|
|
1122
|
+
const { namespace } = this.getFunctionConfig()
|
|
1123
|
+
const { functionName: FunctionName, name: Name, functionVersion: FunctionVersion, routingConfig: RoutingConfig, description: Description } = updateVersionConfigParams
|
|
1124
|
+
|
|
1125
|
+
return this.scfService.request('UpdateAlias', {
|
|
1126
|
+
FunctionName,
|
|
1127
|
+
Name,
|
|
1128
|
+
Namespace: namespace,
|
|
1129
|
+
FunctionVersion,
|
|
1130
|
+
RoutingConfig,
|
|
1131
|
+
Description
|
|
1132
|
+
})
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
/**
|
|
1136
|
+
* 查询函数别名详情
|
|
1137
|
+
* @param {IGetFunctionAlias} params
|
|
1138
|
+
* @returns {Promise<IGetFunctionAliasRes>}
|
|
1139
|
+
* @memberof FunctionService
|
|
1140
|
+
*/
|
|
1141
|
+
@preLazy()
|
|
1142
|
+
public async getFunctionAlias(params: IGetFunctionAlias): Promise<IGetFunctionAliasRes> {
|
|
1143
|
+
const { namespace } = this.getFunctionConfig()
|
|
1144
|
+
const { functionName: FunctionName, name: Name } = params
|
|
1145
|
+
|
|
1146
|
+
return this.scfService.request('GetAlias', {
|
|
1147
|
+
FunctionName,
|
|
1148
|
+
Name,
|
|
1149
|
+
Namespace: namespace
|
|
1150
|
+
})
|
|
1151
|
+
}
|
|
1152
|
+
|
|
916
1153
|
@preLazy()
|
|
917
1154
|
private async createAccessPath(name: string, path: string) {
|
|
918
1155
|
const access = this.environment.getAccessService()
|
package/src/storage/index.ts
CHANGED
|
@@ -62,7 +62,6 @@ export interface IFilesOptions extends IOptions {
|
|
|
62
62
|
ignore?: string | string[]
|
|
63
63
|
// 文件列表
|
|
64
64
|
files: { localPath: string; cloudPath?: string }[]
|
|
65
|
-
|
|
66
65
|
// 重试次数
|
|
67
66
|
retryCount?: number
|
|
68
67
|
// 重试时间间隔(毫秒)
|
|
@@ -146,8 +145,8 @@ export class StorageService {
|
|
|
146
145
|
*/
|
|
147
146
|
@preLazy()
|
|
148
147
|
public async uploadFiles(options: IFilesOptions): Promise<void> {
|
|
149
|
-
const { files, onProgress, parallel, onFileFinish, ignore, retryCount,
|
|
150
|
-
|
|
148
|
+
const { files, onProgress, parallel, onFileFinish, ignore, retryCount, retryInterval } =
|
|
149
|
+
options
|
|
151
150
|
const { bucket, region } = this.getStorageConfig()
|
|
152
151
|
|
|
153
152
|
return this.uploadFilesCustom({
|
|
@@ -455,7 +454,6 @@ export class StorageService {
|
|
|
455
454
|
|
|
456
455
|
const cos = this.getCos(parallel)
|
|
457
456
|
const uploadFiles = Util.promisify(cos.uploadFiles).bind(cos)
|
|
458
|
-
|
|
459
457
|
const params = {
|
|
460
458
|
files: fileList,
|
|
461
459
|
SliceSize: BIG_FILE_SIZE,
|
|
@@ -567,32 +565,42 @@ export class StorageService {
|
|
|
567
565
|
public async downloadDirectory(options: {
|
|
568
566
|
cloudPath: string
|
|
569
567
|
localPath?: string
|
|
568
|
+
parallel?: number
|
|
570
569
|
}): Promise<(NodeJS.ReadableStream | string)[]> {
|
|
571
|
-
const { cloudPath, localPath } = options
|
|
570
|
+
const { cloudPath, localPath, parallel = 20 } = options
|
|
572
571
|
const resolveLocalPath = path.resolve(localPath)
|
|
573
572
|
|
|
574
573
|
checkFullAccess(resolveLocalPath, true)
|
|
575
574
|
|
|
576
575
|
const cloudDirectoryKey = this.getCloudKey(cloudPath)
|
|
577
576
|
const files = await this.walkCloudDir(cloudDirectoryKey)
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
const fileRelativePath = file.Key.replace(cloudDirectoryKey, '')
|
|
581
|
-
// 空路径和文件夹跳过
|
|
582
|
-
if (!fileRelativePath || /\/$/g.test(fileRelativePath)) {
|
|
583
|
-
return
|
|
584
|
-
}
|
|
585
|
-
const localFilePath = path.join(resolveLocalPath, fileRelativePath)
|
|
586
|
-
// 创建文件的父文件夹
|
|
587
|
-
const fileDir = path.dirname(localFilePath)
|
|
588
|
-
await makeDir(fileDir)
|
|
589
|
-
return this.downloadFile({
|
|
590
|
-
cloudPath: file.Key,
|
|
591
|
-
localPath: localFilePath
|
|
592
|
-
})
|
|
577
|
+
const promises = files.map(file => async () => {
|
|
578
|
+
return this.downloadWithFilePath({ file, cloudDirectoryKey, resolveLocalPath })
|
|
593
579
|
})
|
|
580
|
+
const asyncTaskController = new AsyncTaskParallelController(parallel, 50)
|
|
581
|
+
asyncTaskController.loadTasks(promises)
|
|
582
|
+
let res = await asyncTaskController.run()
|
|
583
|
+
const errorIndexArr = []
|
|
594
584
|
|
|
595
|
-
|
|
585
|
+
res.map(
|
|
586
|
+
(item, index) =>
|
|
587
|
+
/Error/gi.test(Object.prototype.toString.call(item)) && errorIndexArr.push(index)
|
|
588
|
+
)
|
|
589
|
+
// 重试逻辑
|
|
590
|
+
if (errorIndexArr.length) {
|
|
591
|
+
const errorFiles = errorIndexArr.map(errorIndex => files[errorIndex])
|
|
592
|
+
asyncTaskController.loadTasks(
|
|
593
|
+
errorFiles.map(file => async () => {
|
|
594
|
+
return this.downloadWithFilePath({ file, cloudDirectoryKey, resolveLocalPath })
|
|
595
|
+
})
|
|
596
|
+
)
|
|
597
|
+
res = await asyncTaskController.run()
|
|
598
|
+
}
|
|
599
|
+
const errorResultArr = this.determineDownLoadResultIsError(res)
|
|
600
|
+
if (errorResultArr.length) {
|
|
601
|
+
throw errorResultArr[0]
|
|
602
|
+
}
|
|
603
|
+
return res
|
|
596
604
|
}
|
|
597
605
|
|
|
598
606
|
/**
|
|
@@ -1190,6 +1198,7 @@ export class StorageService {
|
|
|
1190
1198
|
private async uploadFilesWithRetry({ uploadFiles, options, times, interval, failedFiles }) {
|
|
1191
1199
|
const { files, onFileFinish } = options
|
|
1192
1200
|
const tempFailedFiles = []
|
|
1201
|
+
let curError: any = null
|
|
1193
1202
|
const res = await uploadFiles({
|
|
1194
1203
|
...options,
|
|
1195
1204
|
files: failedFiles.length
|
|
@@ -1199,24 +1208,74 @@ export class StorageService {
|
|
|
1199
1208
|
const error = args[0]
|
|
1200
1209
|
const fileInfo = (args as any)[2]
|
|
1201
1210
|
if (error) {
|
|
1211
|
+
curError = error
|
|
1202
1212
|
tempFailedFiles.push(fileInfo.Key)
|
|
1203
1213
|
}
|
|
1204
1214
|
onFileFinish?.apply(null, args)
|
|
1205
1215
|
}
|
|
1206
1216
|
})
|
|
1207
|
-
if (!tempFailedFiles?.length || times <= 0) return res
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1217
|
+
// if (!tempFailedFiles?.length || times <= 0) return res
|
|
1218
|
+
|
|
1219
|
+
if (!tempFailedFiles?.length) {
|
|
1220
|
+
return res
|
|
1221
|
+
} else {
|
|
1222
|
+
if (times > 0) {
|
|
1223
|
+
return await new Promise((resolve, reject) => {
|
|
1224
|
+
setTimeout(
|
|
1225
|
+
() =>
|
|
1226
|
+
this.uploadFilesWithRetry({
|
|
1227
|
+
uploadFiles,
|
|
1228
|
+
options,
|
|
1229
|
+
times: times - 1,
|
|
1230
|
+
interval,
|
|
1231
|
+
failedFiles: tempFailedFiles
|
|
1232
|
+
}).then(res => resolve(res))
|
|
1233
|
+
.catch(err => reject(err)),
|
|
1234
|
+
interval
|
|
1235
|
+
)
|
|
1236
|
+
})
|
|
1237
|
+
} else {
|
|
1238
|
+
if (curError) {
|
|
1239
|
+
throw curError
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
/**
|
|
1246
|
+
* 拼接路径下载单文件
|
|
1247
|
+
* @param file
|
|
1248
|
+
* @param cloudDirectoryKey
|
|
1249
|
+
* @param resolveLocalPath
|
|
1250
|
+
* @returns
|
|
1251
|
+
*/
|
|
1252
|
+
private async downloadWithFilePath({ file, cloudDirectoryKey, resolveLocalPath }) {
|
|
1253
|
+
const fileRelativePath = file.Key.replace(cloudDirectoryKey, '')
|
|
1254
|
+
// 空路径和文件夹跳过
|
|
1255
|
+
if (!fileRelativePath || /\/$/g.test(fileRelativePath)) {
|
|
1256
|
+
return
|
|
1220
1257
|
}
|
|
1258
|
+
const localFilePath = path.join(resolveLocalPath, fileRelativePath)
|
|
1259
|
+
// 创建文件的父文件夹
|
|
1260
|
+
const fileDir = path.dirname(localFilePath)
|
|
1261
|
+
await makeDir(fileDir)
|
|
1262
|
+
return this.downloadFile({
|
|
1263
|
+
cloudPath: file.Key,
|
|
1264
|
+
localPath: localFilePath
|
|
1265
|
+
})
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
/**
|
|
1269
|
+
* 根据下载结果返回错误列表
|
|
1270
|
+
* @param res
|
|
1271
|
+
* @returns
|
|
1272
|
+
*/
|
|
1273
|
+
private determineDownLoadResultIsError(res) {
|
|
1274
|
+
const resultErrorArr = []
|
|
1275
|
+
res.map(
|
|
1276
|
+
item =>
|
|
1277
|
+
/Error/gi.test(Object.prototype.toString.call(item)) && resultErrorArr.push(item)
|
|
1278
|
+
)
|
|
1279
|
+
return resultErrorArr
|
|
1221
1280
|
}
|
|
1222
1281
|
}
|
|
@@ -87,6 +87,92 @@ export interface IGetLayerVersionRes extends IResponseInfo {
|
|
|
87
87
|
LayerName: string;
|
|
88
88
|
Status: string;
|
|
89
89
|
}
|
|
90
|
+
export interface ISetProvisionedConcurrencyConfig {
|
|
91
|
+
functionName: string;
|
|
92
|
+
qualifier: string;
|
|
93
|
+
versionProvisionedConcurrencyNum: number;
|
|
94
|
+
}
|
|
95
|
+
export interface IGetProvisionedConcurrencyConfig {
|
|
96
|
+
functionName: string;
|
|
97
|
+
qualifier?: string;
|
|
98
|
+
}
|
|
99
|
+
export interface IVersionProvisionedConcurrencyInfo {
|
|
100
|
+
AllocatedProvisionedConcurrencyNum: number;
|
|
101
|
+
AvailableProvisionedConcurrencyNum: number;
|
|
102
|
+
Status: string;
|
|
103
|
+
StatusReason: string;
|
|
104
|
+
Qualifier: string;
|
|
105
|
+
}
|
|
106
|
+
export interface IGetProvisionedConcurrencyRes extends IResponseInfo {
|
|
107
|
+
UnallocatedConcurrencyNum: number;
|
|
108
|
+
Allocated: IVersionProvisionedConcurrencyInfo[];
|
|
109
|
+
}
|
|
110
|
+
export interface IPublishVersionParams {
|
|
111
|
+
functionName: string;
|
|
112
|
+
description?: string;
|
|
113
|
+
}
|
|
114
|
+
export interface IPublishVersionRes extends IResponseInfo {
|
|
115
|
+
FunctionVersion: string;
|
|
116
|
+
CodeSize: number;
|
|
117
|
+
MemorySize: number;
|
|
118
|
+
Description: string;
|
|
119
|
+
Handler: string;
|
|
120
|
+
Timeout: number;
|
|
121
|
+
Runtime: string;
|
|
122
|
+
Namespace: string;
|
|
123
|
+
}
|
|
124
|
+
export interface IListFunctionVersionParams {
|
|
125
|
+
functionName: string;
|
|
126
|
+
offset?: number;
|
|
127
|
+
limit?: number;
|
|
128
|
+
order?: string;
|
|
129
|
+
orderBy?: string;
|
|
130
|
+
}
|
|
131
|
+
export interface IFunctionVersion {
|
|
132
|
+
Version: string;
|
|
133
|
+
Description: string;
|
|
134
|
+
AddTime: string;
|
|
135
|
+
ModTime: string;
|
|
136
|
+
Status: string;
|
|
137
|
+
}
|
|
138
|
+
export interface IFunctionVersionsRes extends IResponseInfo {
|
|
139
|
+
FunctionVersion: string[];
|
|
140
|
+
Versions: IFunctionVersion[];
|
|
141
|
+
TotalCount: number;
|
|
142
|
+
}
|
|
143
|
+
export interface IVersionMatch {
|
|
144
|
+
Version: string;
|
|
145
|
+
Key: string;
|
|
146
|
+
Method: string;
|
|
147
|
+
Expression: string;
|
|
148
|
+
}
|
|
149
|
+
export interface IVersionWeight {
|
|
150
|
+
Version: string;
|
|
151
|
+
Weight: number;
|
|
152
|
+
}
|
|
153
|
+
export interface IRoutingConfig {
|
|
154
|
+
AdditionalVersionWeights?: IVersionWeight[];
|
|
155
|
+
AddtionVersionMatchs?: IVersionMatch[];
|
|
156
|
+
}
|
|
157
|
+
export interface IUpdateFunctionAliasConfig {
|
|
158
|
+
functionName: string;
|
|
159
|
+
name: string;
|
|
160
|
+
functionVersion: string;
|
|
161
|
+
description?: string;
|
|
162
|
+
routingConfig?: IRoutingConfig;
|
|
163
|
+
}
|
|
164
|
+
export interface IGetFunctionAlias {
|
|
165
|
+
functionName: string;
|
|
166
|
+
name: string;
|
|
167
|
+
}
|
|
168
|
+
export interface IGetFunctionAliasRes extends IResponseInfo {
|
|
169
|
+
FunctionVersion: string;
|
|
170
|
+
Name: string;
|
|
171
|
+
RoutingConfig: IRoutingConfig;
|
|
172
|
+
Description: string;
|
|
173
|
+
AddTime: string;
|
|
174
|
+
ModTime: string;
|
|
175
|
+
}
|
|
90
176
|
export declare class FunctionService {
|
|
91
177
|
private environment;
|
|
92
178
|
private vpcService;
|
|
@@ -210,6 +296,58 @@ export declare class FunctionService {
|
|
|
210
296
|
listLayerVersions(options: IVersionListOptions): Promise<IListLayerVersionsRes>;
|
|
211
297
|
listLayers(options: ILayerListOptions): Promise<IListLayerRes>;
|
|
212
298
|
getLayerVersion(options: ILayerOptions): Promise<IGetLayerVersionRes>;
|
|
299
|
+
/**
|
|
300
|
+
* 设置预置并发
|
|
301
|
+
* @private
|
|
302
|
+
* @param {IProvisionedConcurrencyConfig} concurrencyConfig
|
|
303
|
+
* @returns
|
|
304
|
+
* @memberof FunctionService
|
|
305
|
+
*/
|
|
306
|
+
setProvisionedConcurrencyConfig(concurrencyConfig: ISetProvisionedConcurrencyConfig): Promise<IResponseInfo>;
|
|
307
|
+
/**
|
|
308
|
+
* 获取函数预置并发详情
|
|
309
|
+
* @private
|
|
310
|
+
* @param {IGetProvisionedConcurrencyConfig} concurrencyConfig
|
|
311
|
+
* @returns {Promise<IGetProvisionedConcurrencyRes>}
|
|
312
|
+
* @memberof FunctionService
|
|
313
|
+
*/
|
|
314
|
+
getProvisionedConcurrencyConfig(concurrencyConfig: IGetProvisionedConcurrencyConfig): Promise<IGetProvisionedConcurrencyRes>;
|
|
315
|
+
/**
|
|
316
|
+
* 删除预置并发
|
|
317
|
+
* @private
|
|
318
|
+
* @param {IGetProvisionedConcurrencyConfig} concurrencyConfig
|
|
319
|
+
* @returns {Promise<IResponseInfo>}
|
|
320
|
+
* @memberof FunctionService
|
|
321
|
+
*/
|
|
322
|
+
deleteProvisionedConcurrencyConfig(concurrencyConfig: IGetProvisionedConcurrencyConfig): Promise<IResponseInfo>;
|
|
323
|
+
/**
|
|
324
|
+
* 发布新版本
|
|
325
|
+
* @param {IPublishVersionParams} publishParams
|
|
326
|
+
* @returns {Promise<IPublishVersionRes>}
|
|
327
|
+
* @memberof FunctionService
|
|
328
|
+
*/
|
|
329
|
+
publishVersion(publishParams: IPublishVersionParams): Promise<IPublishVersionRes>;
|
|
330
|
+
/**
|
|
331
|
+
* 查询函数版本详情
|
|
332
|
+
* @param {IListFunctionVersionParams} listVersionParams
|
|
333
|
+
* @returns {Promise<IFunctionVersionsRes>}
|
|
334
|
+
* @memberof FunctionService
|
|
335
|
+
*/
|
|
336
|
+
listVersionByFunction(listVersionParams: IListFunctionVersionParams): Promise<IFunctionVersionsRes>;
|
|
337
|
+
/**
|
|
338
|
+
*
|
|
339
|
+
* @param {IUpdateFunctionAliasConfig} updateVersionConfigParams
|
|
340
|
+
* @returns {Promise<IResponseInfo>}
|
|
341
|
+
* @memberof FunctionService
|
|
342
|
+
*/
|
|
343
|
+
updateFunctionAliasConfig(updateVersionConfigParams: IUpdateFunctionAliasConfig): Promise<IResponseInfo>;
|
|
344
|
+
/**
|
|
345
|
+
* 查询函数别名详情
|
|
346
|
+
* @param {IGetFunctionAlias} params
|
|
347
|
+
* @returns {Promise<IGetFunctionAliasRes>}
|
|
348
|
+
* @memberof FunctionService
|
|
349
|
+
*/
|
|
350
|
+
getFunctionAlias(params: IGetFunctionAlias): Promise<IGetFunctionAliasRes>;
|
|
213
351
|
private createAccessPath;
|
|
214
352
|
private getCodeParams;
|
|
215
353
|
private getTempCosInfo;
|
package/types/storage/index.d.ts
CHANGED
|
@@ -151,6 +151,7 @@ export declare class StorageService {
|
|
|
151
151
|
downloadDirectory(options: {
|
|
152
152
|
cloudPath: string;
|
|
153
153
|
localPath?: string;
|
|
154
|
+
parallel?: number;
|
|
154
155
|
}): Promise<(NodeJS.ReadableStream | string)[]>;
|
|
155
156
|
/**
|
|
156
157
|
* 列出文件夹下的文件
|
|
@@ -305,5 +306,19 @@ export declare class StorageService {
|
|
|
305
306
|
* @returns
|
|
306
307
|
*/
|
|
307
308
|
private uploadFilesWithRetry;
|
|
309
|
+
/**
|
|
310
|
+
* 拼接路径下载单文件
|
|
311
|
+
* @param file
|
|
312
|
+
* @param cloudDirectoryKey
|
|
313
|
+
* @param resolveLocalPath
|
|
314
|
+
* @returns
|
|
315
|
+
*/
|
|
316
|
+
private downloadWithFilePath;
|
|
317
|
+
/**
|
|
318
|
+
* 根据下载结果返回错误列表
|
|
319
|
+
* @param res
|
|
320
|
+
* @returns
|
|
321
|
+
*/
|
|
322
|
+
private determineDownLoadResultIsError;
|
|
308
323
|
}
|
|
309
324
|
export {};
|