@cloudbase/manager-node 3.9.4-beta → 3.11.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/context.js +2 -1
- package/lib/env/index.js +7 -2
- package/lib/environment.js +4 -0
- package/lib/hosting/index.js +7 -3
- package/lib/index.js +2 -1
- package/lib/storage/index.js +75 -11
- package/package.json +1 -1
- package/src/context.ts +3 -1
- package/src/env/index.ts +10 -2
- package/src/environment.ts +6 -0
- package/src/hosting/index.ts +17 -3
- package/src/index.ts +3 -1
- package/src/storage/index.ts +117 -25
- package/types/context.d.ts +3 -1
- package/types/env/index.d.ts +1 -0
- package/types/environment.d.ts +2 -0
- package/types/hosting/index.d.ts +4 -0
- package/types/index.d.ts +1 -0
- package/types/storage/index.d.ts +21 -0
- package/.vscode/launch.json +0 -26
- package/.vscode/settings.json +0 -3
package/lib/context.js
CHANGED
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CloudBaseContext = void 0;
|
|
4
4
|
class CloudBaseContext {
|
|
5
|
-
constructor({ secretId = '', secretKey = '', token = '', proxy = '', region = '' }) {
|
|
5
|
+
constructor({ secretId = '', secretKey = '', token = '', proxy = '', region = '', envType = '' }) {
|
|
6
6
|
this.secretId = secretId;
|
|
7
7
|
this.secretKey = secretKey;
|
|
8
8
|
this.token = token;
|
|
9
9
|
this.proxy = proxy;
|
|
10
10
|
this.region = region;
|
|
11
|
+
this.envType = envType;
|
|
11
12
|
}
|
|
12
13
|
}
|
|
13
14
|
exports.CloudBaseContext = CloudBaseContext;
|
package/lib/env/index.js
CHANGED
|
@@ -21,6 +21,7 @@ class EnvService {
|
|
|
21
21
|
constructor(environment) {
|
|
22
22
|
this.environment = environment;
|
|
23
23
|
this.envId = environment.getEnvId();
|
|
24
|
+
this.envType = environment.getEnvType();
|
|
24
25
|
this.cloudService = new utils_1.CloudService(environment.cloudBaseContext, 'tcb', '2018-06-08');
|
|
25
26
|
this.camService = new cam_1.CamService(environment.cloudBaseContext);
|
|
26
27
|
this.billService = new billing_1.BillingService(environment.cloudBaseContext);
|
|
@@ -331,9 +332,13 @@ class EnvService {
|
|
|
331
332
|
*/
|
|
332
333
|
async getEnvInfo() {
|
|
333
334
|
// NOTE: DescribeEnv 接口废弃,需要使用 DescribeEnvs 接口
|
|
334
|
-
const
|
|
335
|
+
const params = {
|
|
335
336
|
EnvId: this.envId
|
|
336
|
-
}
|
|
337
|
+
};
|
|
338
|
+
if (this.envType === 'run') {
|
|
339
|
+
params.EnvType = 'run';
|
|
340
|
+
}
|
|
341
|
+
const { EnvList, RequestId } = await this.cloudService.request('DescribeEnvs', params);
|
|
337
342
|
return {
|
|
338
343
|
EnvInfo: (EnvList === null || EnvList === void 0 ? void 0 : EnvList.length) ? EnvList[0] : {},
|
|
339
344
|
RequestId
|
package/lib/environment.js
CHANGED
|
@@ -19,6 +19,7 @@ class Environment {
|
|
|
19
19
|
this.inited = false;
|
|
20
20
|
this.envId = envId;
|
|
21
21
|
this.cloudBaseContext = context;
|
|
22
|
+
this.envType = context.envType;
|
|
22
23
|
// 拉取当前环境 的环境信息 todo
|
|
23
24
|
this.functionService = new function_1.FunctionService(this);
|
|
24
25
|
this.databaseService = new database_1.DatabaseService(this);
|
|
@@ -49,6 +50,9 @@ class Environment {
|
|
|
49
50
|
getEnvId() {
|
|
50
51
|
return this.envId;
|
|
51
52
|
}
|
|
53
|
+
getEnvType() {
|
|
54
|
+
return this.envType;
|
|
55
|
+
}
|
|
52
56
|
getStorageService() {
|
|
53
57
|
return this.storageService;
|
|
54
58
|
}
|
package/lib/hosting/index.js
CHANGED
|
@@ -131,7 +131,7 @@ class HostingService {
|
|
|
131
131
|
* @param options
|
|
132
132
|
*/
|
|
133
133
|
async uploadFiles(options) {
|
|
134
|
-
const { localPath, cloudPath, files = [], onProgress, onFileFinish, parallel = 20, ignore } = options;
|
|
134
|
+
const { localPath, cloudPath, files = [], onProgress, onFileFinish, parallel = 20, ignore, retryCount, retryInterval } = options;
|
|
135
135
|
const hosting = await this.checkStatus();
|
|
136
136
|
const { Bucket, Regoin } = hosting;
|
|
137
137
|
const storageService = await this.environment.getStorageService();
|
|
@@ -150,7 +150,9 @@ class HostingService {
|
|
|
150
150
|
onProgress,
|
|
151
151
|
onFileFinish,
|
|
152
152
|
fileId: false,
|
|
153
|
-
ignore
|
|
153
|
+
ignore,
|
|
154
|
+
retryCount,
|
|
155
|
+
retryInterval,
|
|
154
156
|
});
|
|
155
157
|
}
|
|
156
158
|
else {
|
|
@@ -171,7 +173,9 @@ class HostingService {
|
|
|
171
173
|
bucket: Bucket,
|
|
172
174
|
region: Regoin,
|
|
173
175
|
files: uploadFiles,
|
|
174
|
-
fileId: false
|
|
176
|
+
fileId: false,
|
|
177
|
+
retryCount,
|
|
178
|
+
retryInterval,
|
|
175
179
|
});
|
|
176
180
|
}
|
|
177
181
|
/**
|
package/lib/index.js
CHANGED
|
@@ -4,7 +4,7 @@ const environmentManager_1 = require("./environmentManager");
|
|
|
4
4
|
class CloudBase {
|
|
5
5
|
constructor(config = {}) {
|
|
6
6
|
this.cloudBaseConfig = {};
|
|
7
|
-
let { secretId, secretKey, token, envId, proxy, region } = config;
|
|
7
|
+
let { secretId, secretKey, token, envId, proxy, region, envType } = config;
|
|
8
8
|
// config 中传入的 secretId secretkey 必须同时存在
|
|
9
9
|
if ((secretId && !secretKey) || (!secretId && secretKey)) {
|
|
10
10
|
throw new Error('secretId and secretKey must be a pair');
|
|
@@ -14,6 +14,7 @@ class CloudBase {
|
|
|
14
14
|
secretKey,
|
|
15
15
|
token,
|
|
16
16
|
envId,
|
|
17
|
+
envType,
|
|
17
18
|
proxy,
|
|
18
19
|
region
|
|
19
20
|
};
|
package/lib/storage/index.js
CHANGED
|
@@ -49,7 +49,7 @@ class StorageService {
|
|
|
49
49
|
* @param options
|
|
50
50
|
*/
|
|
51
51
|
async uploadFiles(options) {
|
|
52
|
-
const { files, onProgress, parallel, onFileFinish, ignore } = options;
|
|
52
|
+
const { files, onProgress, parallel, onFileFinish, ignore, retryCount, retryInterval } = options;
|
|
53
53
|
const { bucket, region } = this.getStorageConfig();
|
|
54
54
|
return this.uploadFilesCustom({
|
|
55
55
|
files,
|
|
@@ -58,7 +58,9 @@ class StorageService {
|
|
|
58
58
|
ignore,
|
|
59
59
|
parallel,
|
|
60
60
|
onProgress,
|
|
61
|
-
onFileFinish
|
|
61
|
+
onFileFinish,
|
|
62
|
+
retryCount,
|
|
63
|
+
retryInterval
|
|
62
64
|
});
|
|
63
65
|
}
|
|
64
66
|
/**
|
|
@@ -134,18 +136,24 @@ class StorageService {
|
|
|
134
136
|
* 上传文件夹
|
|
135
137
|
* @param {string} localPath 本地文件夹路径
|
|
136
138
|
* @param {string} cloudPath 云端文件夹
|
|
139
|
+
* @param {number} parallel 并发量
|
|
140
|
+
* @param {number} retryCount 重试次数
|
|
141
|
+
* @param {number} retryInterval 重试时间间隔(毫秒)
|
|
137
142
|
* @param {(string | string[])} ignore
|
|
138
143
|
* @param {(string | string[])} ignore
|
|
139
144
|
* @returns {Promise<void>}
|
|
140
145
|
*/
|
|
141
146
|
async uploadDirectory(options) {
|
|
142
|
-
const { localPath, cloudPath = '', ignore, onProgress, onFileFinish } = options;
|
|
147
|
+
const { localPath, cloudPath = '', ignore, onProgress, onFileFinish, parallel, retryCount, retryInterval } = options;
|
|
143
148
|
// 此处不检查路径是否存在
|
|
144
149
|
// 绝对路径 /var/blog/xxxx
|
|
145
150
|
const { bucket, region } = this.getStorageConfig();
|
|
146
151
|
return this.uploadDirectoryCustom({
|
|
147
152
|
localPath,
|
|
148
153
|
cloudPath,
|
|
154
|
+
parallel,
|
|
155
|
+
retryCount,
|
|
156
|
+
retryInterval,
|
|
149
157
|
bucket,
|
|
150
158
|
region,
|
|
151
159
|
ignore,
|
|
@@ -157,13 +165,16 @@ class StorageService {
|
|
|
157
165
|
* 上传文件夹,支持自定义 Region 和 Bucket
|
|
158
166
|
* @param {string} localPath
|
|
159
167
|
* @param {string} cloudPath
|
|
168
|
+
* @param {number} parallel
|
|
169
|
+
* @param {number} retryCount
|
|
170
|
+
* @param {number} retryInterval
|
|
160
171
|
* @param {string} bucket
|
|
161
172
|
* @param {string} region
|
|
162
173
|
* @param {IOptions} options
|
|
163
174
|
* @returns {Promise<void>}
|
|
164
175
|
*/
|
|
165
176
|
async uploadDirectoryCustom(options) {
|
|
166
|
-
const { localPath, cloudPath, bucket, region, onProgress, onFileFinish, ignore, fileId = true, parallel = 20 } = options;
|
|
177
|
+
const { localPath, cloudPath, bucket, region, onProgress, onFileFinish, ignore, fileId = true, parallel = 20, retryCount = 0, retryInterval = 500 } = options;
|
|
167
178
|
// 此处不检查路径是否存在
|
|
168
179
|
// 绝对路径 /var/blog/xxxx
|
|
169
180
|
const resolvePath = path_1.default.resolve(localPath);
|
|
@@ -229,11 +240,18 @@ class StorageService {
|
|
|
229
240
|
// 对文件上传进行处理
|
|
230
241
|
const cos = this.getCos(parallel);
|
|
231
242
|
const uploadFiles = util_1.default.promisify(cos.uploadFiles).bind(cos);
|
|
232
|
-
|
|
243
|
+
const params = {
|
|
233
244
|
files,
|
|
234
245
|
SliceSize: BIG_FILE_SIZE,
|
|
235
246
|
onProgress,
|
|
236
247
|
onFileFinish
|
|
248
|
+
};
|
|
249
|
+
return this.uploadFilesWithRetry({
|
|
250
|
+
uploadFiles,
|
|
251
|
+
options: params,
|
|
252
|
+
times: retryCount,
|
|
253
|
+
interval: retryInterval,
|
|
254
|
+
failedFiles: []
|
|
237
255
|
});
|
|
238
256
|
}
|
|
239
257
|
/**
|
|
@@ -241,7 +259,7 @@ class StorageService {
|
|
|
241
259
|
* @param options
|
|
242
260
|
*/
|
|
243
261
|
async uploadFilesCustom(options) {
|
|
244
|
-
const { files, bucket, region, ignore, onProgress, onFileFinish, fileId = true, parallel = 20 } = options;
|
|
262
|
+
const { files, bucket, region, ignore, onProgress, onFileFinish, fileId = true, parallel = 20, retryCount = 0, retryInterval = 500 } = options;
|
|
245
263
|
if (!files || !files.length) {
|
|
246
264
|
return;
|
|
247
265
|
}
|
|
@@ -275,11 +293,24 @@ class StorageService {
|
|
|
275
293
|
fileList = await asyncTaskController.run();
|
|
276
294
|
const cos = this.getCos(parallel);
|
|
277
295
|
const uploadFiles = util_1.default.promisify(cos.uploadFiles).bind(cos);
|
|
278
|
-
|
|
279
|
-
onProgress,
|
|
280
|
-
onFileFinish,
|
|
296
|
+
const params = {
|
|
281
297
|
files: fileList,
|
|
282
|
-
SliceSize: BIG_FILE_SIZE
|
|
298
|
+
SliceSize: BIG_FILE_SIZE,
|
|
299
|
+
onProgress,
|
|
300
|
+
onFileFinish
|
|
301
|
+
};
|
|
302
|
+
// return uploadFiles({
|
|
303
|
+
// onProgress,
|
|
304
|
+
// onFileFinish,
|
|
305
|
+
// files: fileList,
|
|
306
|
+
// SliceSize: BIG_FILE_SIZE
|
|
307
|
+
// })
|
|
308
|
+
return this.uploadFilesWithRetry({
|
|
309
|
+
uploadFiles,
|
|
310
|
+
options: params,
|
|
311
|
+
times: retryCount,
|
|
312
|
+
interval: retryInterval,
|
|
313
|
+
failedFiles: []
|
|
283
314
|
});
|
|
284
315
|
}
|
|
285
316
|
/**
|
|
@@ -774,7 +805,6 @@ class StorageService {
|
|
|
774
805
|
params.WebsiteConfiguration.RoutingRules.push(routeItem);
|
|
775
806
|
}
|
|
776
807
|
}
|
|
777
|
-
console.log('params:', JSON.stringify(params));
|
|
778
808
|
const res = await putBucketWebsite(params);
|
|
779
809
|
return res;
|
|
780
810
|
}
|
|
@@ -847,6 +877,40 @@ class StorageService {
|
|
|
847
877
|
env: envConfig.EnvId
|
|
848
878
|
};
|
|
849
879
|
}
|
|
880
|
+
/**
|
|
881
|
+
* 带重试功能的上传多文件函数
|
|
882
|
+
* @param uploadFiles sdk上传函数
|
|
883
|
+
* @param options sdk上传函数参数
|
|
884
|
+
* @param times 重试次数
|
|
885
|
+
* @param interval 重试时间间隔(毫秒)
|
|
886
|
+
* @param failedFiles 失败文件列表
|
|
887
|
+
* @returns
|
|
888
|
+
*/
|
|
889
|
+
async uploadFilesWithRetry({ uploadFiles, options, times, interval, failedFiles }) {
|
|
890
|
+
const { files, onFileFinish } = options;
|
|
891
|
+
const tempFailedFiles = [];
|
|
892
|
+
const res = await uploadFiles(Object.assign(Object.assign({}, options), { files: failedFiles.length
|
|
893
|
+
? files.filter(file => failedFiles.includes(file.Key))
|
|
894
|
+
: files, onFileFinish: (...args) => {
|
|
895
|
+
const error = args[0];
|
|
896
|
+
const fileInfo = args[2];
|
|
897
|
+
if (error) {
|
|
898
|
+
tempFailedFiles.push(fileInfo.Key);
|
|
899
|
+
}
|
|
900
|
+
onFileFinish === null || onFileFinish === void 0 ? void 0 : onFileFinish.apply(null, args);
|
|
901
|
+
} }));
|
|
902
|
+
if (!(tempFailedFiles === null || tempFailedFiles === void 0 ? void 0 : tempFailedFiles.length) || times <= 0)
|
|
903
|
+
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
|
+
}
|
|
913
|
+
}
|
|
850
914
|
}
|
|
851
915
|
__decorate([
|
|
852
916
|
utils_1.preLazy()
|
package/package.json
CHANGED
package/src/context.ts
CHANGED
|
@@ -5,12 +5,14 @@ export class CloudBaseContext {
|
|
|
5
5
|
public readonly proxy: string
|
|
6
6
|
public readonly envId: string
|
|
7
7
|
public readonly region: string
|
|
8
|
+
public readonly envType: string // baas/run/weda/hosting
|
|
8
9
|
|
|
9
|
-
constructor({ secretId = '', secretKey = '', token = '', proxy = '', region = '' }) {
|
|
10
|
+
constructor({ secretId = '', secretKey = '', token = '', proxy = '', region = '', envType = '' }) {
|
|
10
11
|
this.secretId = secretId
|
|
11
12
|
this.secretKey = secretKey
|
|
12
13
|
this.token = token
|
|
13
14
|
this.proxy = proxy
|
|
14
15
|
this.region = region
|
|
16
|
+
this.envType = envType
|
|
15
17
|
}
|
|
16
18
|
}
|
package/src/env/index.ts
CHANGED
|
@@ -64,10 +64,12 @@ export class EnvService {
|
|
|
64
64
|
private cloudService: CloudService
|
|
65
65
|
private camService: CamService
|
|
66
66
|
private billService: BillingService
|
|
67
|
+
private envType?: string
|
|
67
68
|
|
|
68
69
|
constructor(environment: Environment) {
|
|
69
70
|
this.environment = environment
|
|
70
71
|
this.envId = environment.getEnvId()
|
|
72
|
+
this.envType = environment.getEnvType()
|
|
71
73
|
this.cloudService = new CloudService(environment.cloudBaseContext, 'tcb', '2018-06-08')
|
|
72
74
|
this.camService = new CamService(environment.cloudBaseContext)
|
|
73
75
|
this.billService = new BillingService(environment.cloudBaseContext)
|
|
@@ -420,9 +422,15 @@ export class EnvService {
|
|
|
420
422
|
RequestId: string
|
|
421
423
|
}> {
|
|
422
424
|
// NOTE: DescribeEnv 接口废弃,需要使用 DescribeEnvs 接口
|
|
423
|
-
const
|
|
425
|
+
const params: any = {
|
|
424
426
|
EnvId: this.envId
|
|
425
|
-
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
if (this.envType === 'run') {
|
|
430
|
+
params.EnvType = 'run'
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
const { EnvList, RequestId } = await this.cloudService.request('DescribeEnvs', params)
|
|
426
434
|
|
|
427
435
|
return {
|
|
428
436
|
EnvInfo: EnvList?.length ? EnvList[0] : {},
|
package/src/environment.ts
CHANGED
|
@@ -21,6 +21,7 @@ export class Environment {
|
|
|
21
21
|
public cloudBaseContext: CloudBaseContext
|
|
22
22
|
public lazyEnvironmentConfig: EnvInfo
|
|
23
23
|
private envId: string
|
|
24
|
+
private envType?: string
|
|
24
25
|
|
|
25
26
|
private functionService: FunctionService
|
|
26
27
|
private databaseService: DatabaseService
|
|
@@ -35,6 +36,7 @@ export class Environment {
|
|
|
35
36
|
constructor(context: CloudBaseContext, envId: string) {
|
|
36
37
|
this.envId = envId
|
|
37
38
|
this.cloudBaseContext = context
|
|
39
|
+
this.envType = context.envType
|
|
38
40
|
|
|
39
41
|
// 拉取当前环境 的环境信息 todo
|
|
40
42
|
this.functionService = new FunctionService(this)
|
|
@@ -69,6 +71,10 @@ export class Environment {
|
|
|
69
71
|
return this.envId
|
|
70
72
|
}
|
|
71
73
|
|
|
74
|
+
public getEnvType(): string {
|
|
75
|
+
return this.envType
|
|
76
|
+
}
|
|
77
|
+
|
|
72
78
|
public getStorageService(): StorageService {
|
|
73
79
|
return this.storageService
|
|
74
80
|
}
|
package/src/hosting/index.ts
CHANGED
|
@@ -38,6 +38,10 @@ export interface IHostingFileOptions {
|
|
|
38
38
|
onProgress?: OnProgress
|
|
39
39
|
onFileFinish?: OnFileFinish
|
|
40
40
|
ignore?: string | string[]
|
|
41
|
+
// 重试次数
|
|
42
|
+
retryCount?: number
|
|
43
|
+
// 重试时间间隔(毫秒)
|
|
44
|
+
retryInterval?: number
|
|
41
45
|
}
|
|
42
46
|
|
|
43
47
|
export interface IHostingFilesOptions {
|
|
@@ -52,6 +56,10 @@ export interface IHostingFilesOptions {
|
|
|
52
56
|
onProgress?: OnProgress
|
|
53
57
|
onFileFinish?: OnFileFinish
|
|
54
58
|
ignore?: string | string[]
|
|
59
|
+
// 重试次数
|
|
60
|
+
retryCount?: number
|
|
61
|
+
// 重试时间间隔(毫秒)
|
|
62
|
+
retryInterval?: number
|
|
55
63
|
}
|
|
56
64
|
|
|
57
65
|
export type IHostingOptions = IHostingFileOptions | IHostingFilesOptions
|
|
@@ -331,7 +339,9 @@ export class HostingService {
|
|
|
331
339
|
onProgress,
|
|
332
340
|
onFileFinish,
|
|
333
341
|
parallel = 20,
|
|
334
|
-
ignore
|
|
342
|
+
ignore,
|
|
343
|
+
retryCount,
|
|
344
|
+
retryInterval
|
|
335
345
|
} = options
|
|
336
346
|
|
|
337
347
|
const hosting = await this.checkStatus()
|
|
@@ -355,7 +365,9 @@ export class HostingService {
|
|
|
355
365
|
onProgress,
|
|
356
366
|
onFileFinish,
|
|
357
367
|
fileId: false,
|
|
358
|
-
ignore
|
|
368
|
+
ignore,
|
|
369
|
+
retryCount,
|
|
370
|
+
retryInterval,
|
|
359
371
|
})
|
|
360
372
|
} else {
|
|
361
373
|
// 文件上传统一通过批量上传接口
|
|
@@ -376,7 +388,9 @@ export class HostingService {
|
|
|
376
388
|
bucket: Bucket,
|
|
377
389
|
region: Regoin,
|
|
378
390
|
files: uploadFiles,
|
|
379
|
-
fileId: false
|
|
391
|
+
fileId: false,
|
|
392
|
+
retryCount,
|
|
393
|
+
retryInterval,
|
|
380
394
|
})
|
|
381
395
|
}
|
|
382
396
|
|
package/src/index.ts
CHANGED
|
@@ -19,6 +19,7 @@ interface CloudBaseConfig {
|
|
|
19
19
|
envId?: string
|
|
20
20
|
proxy?: string
|
|
21
21
|
region?: string
|
|
22
|
+
envType?: string
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
class CloudBase {
|
|
@@ -45,7 +46,7 @@ class CloudBase {
|
|
|
45
46
|
private environmentManager: EnvironmentManager
|
|
46
47
|
|
|
47
48
|
public constructor(config: CloudBaseConfig = {}) {
|
|
48
|
-
let { secretId, secretKey, token, envId, proxy, region } = config
|
|
49
|
+
let { secretId, secretKey, token, envId, proxy, region, envType } = config
|
|
49
50
|
// config 中传入的 secretId secretkey 必须同时存在
|
|
50
51
|
if ((secretId && !secretKey) || (!secretId && secretKey)) {
|
|
51
52
|
throw new Error('secretId and secretKey must be a pair')
|
|
@@ -56,6 +57,7 @@ class CloudBase {
|
|
|
56
57
|
secretKey,
|
|
57
58
|
token,
|
|
58
59
|
envId,
|
|
60
|
+
envType,
|
|
59
61
|
proxy,
|
|
60
62
|
region
|
|
61
63
|
}
|
package/src/storage/index.ts
CHANGED
|
@@ -49,6 +49,12 @@ export interface IFileOptions extends IOptions {
|
|
|
49
49
|
localPath: string
|
|
50
50
|
// cloudPath 可以为空
|
|
51
51
|
cloudPath?: string
|
|
52
|
+
// 并发数量
|
|
53
|
+
parallel?: number
|
|
54
|
+
// 重试次数
|
|
55
|
+
retryCount?: number
|
|
56
|
+
// 重试时间间隔(毫秒)
|
|
57
|
+
retryInterval?: number
|
|
52
58
|
}
|
|
53
59
|
|
|
54
60
|
export interface IFilesOptions extends IOptions {
|
|
@@ -56,6 +62,11 @@ export interface IFilesOptions extends IOptions {
|
|
|
56
62
|
ignore?: string | string[]
|
|
57
63
|
// 文件列表
|
|
58
64
|
files: { localPath: string; cloudPath?: string }[]
|
|
65
|
+
|
|
66
|
+
// 重试次数
|
|
67
|
+
retryCount?: number
|
|
68
|
+
// 重试时间间隔(毫秒)
|
|
69
|
+
retryInterval?: number
|
|
59
70
|
}
|
|
60
71
|
|
|
61
72
|
export interface ICustomOptions {
|
|
@@ -135,7 +146,8 @@ export class StorageService {
|
|
|
135
146
|
*/
|
|
136
147
|
@preLazy()
|
|
137
148
|
public async uploadFiles(options: IFilesOptions): Promise<void> {
|
|
138
|
-
const { files, onProgress, parallel, onFileFinish, ignore
|
|
149
|
+
const { files, onProgress, parallel, onFileFinish, ignore, retryCount,
|
|
150
|
+
retryInterval } = options
|
|
139
151
|
const { bucket, region } = this.getStorageConfig()
|
|
140
152
|
|
|
141
153
|
return this.uploadFilesCustom({
|
|
@@ -145,7 +157,9 @@ export class StorageService {
|
|
|
145
157
|
ignore,
|
|
146
158
|
parallel,
|
|
147
159
|
onProgress,
|
|
148
|
-
onFileFinish
|
|
160
|
+
onFileFinish,
|
|
161
|
+
retryCount,
|
|
162
|
+
retryInterval
|
|
149
163
|
})
|
|
150
164
|
}
|
|
151
165
|
|
|
@@ -230,19 +244,34 @@ export class StorageService {
|
|
|
230
244
|
* 上传文件夹
|
|
231
245
|
* @param {string} localPath 本地文件夹路径
|
|
232
246
|
* @param {string} cloudPath 云端文件夹
|
|
247
|
+
* @param {number} parallel 并发量
|
|
248
|
+
* @param {number} retryCount 重试次数
|
|
249
|
+
* @param {number} retryInterval 重试时间间隔(毫秒)
|
|
233
250
|
* @param {(string | string[])} ignore
|
|
234
251
|
* @param {(string | string[])} ignore
|
|
235
252
|
* @returns {Promise<void>}
|
|
236
253
|
*/
|
|
237
254
|
@preLazy()
|
|
238
255
|
public async uploadDirectory(options: IFileOptions): Promise<void> {
|
|
239
|
-
const {
|
|
256
|
+
const {
|
|
257
|
+
localPath,
|
|
258
|
+
cloudPath = '',
|
|
259
|
+
ignore,
|
|
260
|
+
onProgress,
|
|
261
|
+
onFileFinish,
|
|
262
|
+
parallel,
|
|
263
|
+
retryCount,
|
|
264
|
+
retryInterval
|
|
265
|
+
} = options
|
|
240
266
|
// 此处不检查路径是否存在
|
|
241
267
|
// 绝对路径 /var/blog/xxxx
|
|
242
268
|
const { bucket, region } = this.getStorageConfig()
|
|
243
269
|
return this.uploadDirectoryCustom({
|
|
244
270
|
localPath,
|
|
245
271
|
cloudPath,
|
|
272
|
+
parallel,
|
|
273
|
+
retryCount,
|
|
274
|
+
retryInterval,
|
|
246
275
|
bucket,
|
|
247
276
|
region,
|
|
248
277
|
ignore,
|
|
@@ -255,6 +284,9 @@ export class StorageService {
|
|
|
255
284
|
* 上传文件夹,支持自定义 Region 和 Bucket
|
|
256
285
|
* @param {string} localPath
|
|
257
286
|
* @param {string} cloudPath
|
|
287
|
+
* @param {number} parallel
|
|
288
|
+
* @param {number} retryCount
|
|
289
|
+
* @param {number} retryInterval
|
|
258
290
|
* @param {string} bucket
|
|
259
291
|
* @param {string} region
|
|
260
292
|
* @param {IOptions} options
|
|
@@ -271,7 +303,9 @@ export class StorageService {
|
|
|
271
303
|
onFileFinish,
|
|
272
304
|
ignore,
|
|
273
305
|
fileId = true,
|
|
274
|
-
parallel = 20
|
|
306
|
+
parallel = 20,
|
|
307
|
+
retryCount = 0,
|
|
308
|
+
retryInterval = 500
|
|
275
309
|
} = options
|
|
276
310
|
// 此处不检查路径是否存在
|
|
277
311
|
// 绝对路径 /var/blog/xxxx
|
|
@@ -310,12 +344,13 @@ export class StorageService {
|
|
|
310
344
|
const creatingDirController = new AsyncTaskParallelController(parallel, 50)
|
|
311
345
|
const creatingDirTasks = fileStatsList
|
|
312
346
|
.filter(info => info.isDir)
|
|
313
|
-
.map(
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
347
|
+
.map(
|
|
348
|
+
info => () =>
|
|
349
|
+
this.createCloudDirectroyCustom({
|
|
350
|
+
cloudPath: info.cloudFileKey,
|
|
351
|
+
bucket,
|
|
352
|
+
region
|
|
353
|
+
})
|
|
319
354
|
)
|
|
320
355
|
|
|
321
356
|
creatingDirController.loadTasks(creatingDirTasks)
|
|
@@ -348,15 +383,20 @@ export class StorageService {
|
|
|
348
383
|
// 对文件上传进行处理
|
|
349
384
|
const cos = this.getCos(parallel)
|
|
350
385
|
const uploadFiles = Util.promisify(cos.uploadFiles).bind(cos)
|
|
351
|
-
|
|
352
|
-
return uploadFiles({
|
|
386
|
+
const params = {
|
|
353
387
|
files,
|
|
354
388
|
SliceSize: BIG_FILE_SIZE,
|
|
355
389
|
onProgress,
|
|
356
390
|
onFileFinish
|
|
391
|
+
}
|
|
392
|
+
return this.uploadFilesWithRetry({
|
|
393
|
+
uploadFiles,
|
|
394
|
+
options: params,
|
|
395
|
+
times: retryCount,
|
|
396
|
+
interval: retryInterval,
|
|
397
|
+
failedFiles: []
|
|
357
398
|
})
|
|
358
399
|
}
|
|
359
|
-
|
|
360
400
|
/**
|
|
361
401
|
* 批量上传文件
|
|
362
402
|
* @param options
|
|
@@ -371,7 +411,9 @@ export class StorageService {
|
|
|
371
411
|
onProgress,
|
|
372
412
|
onFileFinish,
|
|
373
413
|
fileId = true,
|
|
374
|
-
parallel = 20
|
|
414
|
+
parallel = 20,
|
|
415
|
+
retryCount = 0,
|
|
416
|
+
retryInterval = 500
|
|
375
417
|
} = options
|
|
376
418
|
|
|
377
419
|
if (!files || !files.length) {
|
|
@@ -414,11 +456,25 @@ export class StorageService {
|
|
|
414
456
|
const cos = this.getCos(parallel)
|
|
415
457
|
const uploadFiles = Util.promisify(cos.uploadFiles).bind(cos)
|
|
416
458
|
|
|
417
|
-
|
|
418
|
-
onProgress,
|
|
419
|
-
onFileFinish,
|
|
459
|
+
const params = {
|
|
420
460
|
files: fileList,
|
|
421
|
-
SliceSize: BIG_FILE_SIZE
|
|
461
|
+
SliceSize: BIG_FILE_SIZE,
|
|
462
|
+
onProgress,
|
|
463
|
+
onFileFinish
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// return uploadFiles({
|
|
467
|
+
// onProgress,
|
|
468
|
+
// onFileFinish,
|
|
469
|
+
// files: fileList,
|
|
470
|
+
// SliceSize: BIG_FILE_SIZE
|
|
471
|
+
// })
|
|
472
|
+
return this.uploadFilesWithRetry({
|
|
473
|
+
uploadFiles,
|
|
474
|
+
options: params,
|
|
475
|
+
times: retryCount,
|
|
476
|
+
interval: retryInterval,
|
|
477
|
+
failedFiles: []
|
|
422
478
|
})
|
|
423
479
|
}
|
|
424
480
|
|
|
@@ -735,9 +791,7 @@ export class StorageService {
|
|
|
735
791
|
* @returns {Promise<void>}
|
|
736
792
|
*/
|
|
737
793
|
@preLazy()
|
|
738
|
-
public async deleteDirectory(
|
|
739
|
-
cloudPath: string
|
|
740
|
-
): Promise<{
|
|
794
|
+
public async deleteDirectory(cloudPath: string): Promise<{
|
|
741
795
|
Deleted: { Key: string }[]
|
|
742
796
|
Error: Object[]
|
|
743
797
|
}> {
|
|
@@ -758,9 +812,7 @@ export class StorageService {
|
|
|
758
812
|
* @returns {Promise<void>}
|
|
759
813
|
*/
|
|
760
814
|
@preLazy()
|
|
761
|
-
public async deleteDirectoryCustom(
|
|
762
|
-
options: { cloudPath: string } & ICustomOptions
|
|
763
|
-
): Promise<{
|
|
815
|
+
public async deleteDirectoryCustom(options: { cloudPath: string } & ICustomOptions): Promise<{
|
|
764
816
|
Deleted: { Key: string }[]
|
|
765
817
|
Error: Object[]
|
|
766
818
|
}> {
|
|
@@ -1040,7 +1092,6 @@ export class StorageService {
|
|
|
1040
1092
|
}
|
|
1041
1093
|
}
|
|
1042
1094
|
|
|
1043
|
-
console.log('params:', JSON.stringify(params))
|
|
1044
1095
|
const res = await putBucketWebsite(params)
|
|
1045
1096
|
|
|
1046
1097
|
return res
|
|
@@ -1127,4 +1178,45 @@ export class StorageService {
|
|
|
1127
1178
|
env: envConfig.EnvId
|
|
1128
1179
|
}
|
|
1129
1180
|
}
|
|
1181
|
+
/**
|
|
1182
|
+
* 带重试功能的上传多文件函数
|
|
1183
|
+
* @param uploadFiles sdk上传函数
|
|
1184
|
+
* @param options sdk上传函数参数
|
|
1185
|
+
* @param times 重试次数
|
|
1186
|
+
* @param interval 重试时间间隔(毫秒)
|
|
1187
|
+
* @param failedFiles 失败文件列表
|
|
1188
|
+
* @returns
|
|
1189
|
+
*/
|
|
1190
|
+
private async uploadFilesWithRetry({ uploadFiles, options, times, interval, failedFiles }) {
|
|
1191
|
+
const { files, onFileFinish } = options
|
|
1192
|
+
const tempFailedFiles = []
|
|
1193
|
+
const res = await uploadFiles({
|
|
1194
|
+
...options,
|
|
1195
|
+
files: failedFiles.length
|
|
1196
|
+
? files.filter(file => failedFiles.includes(file.Key))
|
|
1197
|
+
: files,
|
|
1198
|
+
onFileFinish: (...args) => {
|
|
1199
|
+
const error = args[0]
|
|
1200
|
+
const fileInfo = (args as any)[2]
|
|
1201
|
+
if (error) {
|
|
1202
|
+
tempFailedFiles.push(fileInfo.Key)
|
|
1203
|
+
}
|
|
1204
|
+
onFileFinish?.apply(null, args)
|
|
1205
|
+
}
|
|
1206
|
+
})
|
|
1207
|
+
if (!tempFailedFiles?.length || times <= 0) return res
|
|
1208
|
+
if (times > 0) {
|
|
1209
|
+
setTimeout(
|
|
1210
|
+
() =>
|
|
1211
|
+
this.uploadFilesWithRetry({
|
|
1212
|
+
uploadFiles,
|
|
1213
|
+
options,
|
|
1214
|
+
times: times - 1,
|
|
1215
|
+
interval,
|
|
1216
|
+
failedFiles: tempFailedFiles
|
|
1217
|
+
}),
|
|
1218
|
+
interval
|
|
1219
|
+
)
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1130
1222
|
}
|
package/types/context.d.ts
CHANGED
|
@@ -5,11 +5,13 @@ export declare class CloudBaseContext {
|
|
|
5
5
|
readonly proxy: string;
|
|
6
6
|
readonly envId: string;
|
|
7
7
|
readonly region: string;
|
|
8
|
-
|
|
8
|
+
readonly envType: string;
|
|
9
|
+
constructor({ secretId, secretKey, token, proxy, region, envType }: {
|
|
9
10
|
secretId?: string;
|
|
10
11
|
secretKey?: string;
|
|
11
12
|
token?: string;
|
|
12
13
|
proxy?: string;
|
|
13
14
|
region?: string;
|
|
15
|
+
envType?: string;
|
|
14
16
|
});
|
|
15
17
|
}
|
package/types/env/index.d.ts
CHANGED
package/types/environment.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export declare class Environment {
|
|
|
15
15
|
cloudBaseContext: CloudBaseContext;
|
|
16
16
|
lazyEnvironmentConfig: EnvInfo;
|
|
17
17
|
private envId;
|
|
18
|
+
private envType?;
|
|
18
19
|
private functionService;
|
|
19
20
|
private databaseService;
|
|
20
21
|
private storageService;
|
|
@@ -27,6 +28,7 @@ export declare class Environment {
|
|
|
27
28
|
constructor(context: CloudBaseContext, envId: string);
|
|
28
29
|
lazyInit(): Promise<any>;
|
|
29
30
|
getEnvId(): string;
|
|
31
|
+
getEnvType(): string;
|
|
30
32
|
getStorageService(): StorageService;
|
|
31
33
|
getDatabaseService(): DatabaseService;
|
|
32
34
|
getFunctionService(): FunctionService;
|
package/types/hosting/index.d.ts
CHANGED
|
@@ -20,6 +20,8 @@ export interface IHostingFileOptions {
|
|
|
20
20
|
onProgress?: OnProgress;
|
|
21
21
|
onFileFinish?: OnFileFinish;
|
|
22
22
|
ignore?: string | string[];
|
|
23
|
+
retryCount?: number;
|
|
24
|
+
retryInterval?: number;
|
|
23
25
|
}
|
|
24
26
|
export interface IHostingFilesOptions {
|
|
25
27
|
localPath?: string;
|
|
@@ -32,6 +34,8 @@ export interface IHostingFilesOptions {
|
|
|
32
34
|
onProgress?: OnProgress;
|
|
33
35
|
onFileFinish?: OnFileFinish;
|
|
34
36
|
ignore?: string | string[];
|
|
37
|
+
retryCount?: number;
|
|
38
|
+
retryInterval?: number;
|
|
35
39
|
}
|
|
36
40
|
export declare type IHostingOptions = IHostingFileOptions | IHostingFilesOptions;
|
|
37
41
|
export interface IHostingCloudOptions {
|
package/types/index.d.ts
CHANGED
package/types/storage/index.d.ts
CHANGED
|
@@ -17,6 +17,9 @@ export interface IOptions {
|
|
|
17
17
|
export interface IFileOptions extends IOptions {
|
|
18
18
|
localPath: string;
|
|
19
19
|
cloudPath?: string;
|
|
20
|
+
parallel?: number;
|
|
21
|
+
retryCount?: number;
|
|
22
|
+
retryInterval?: number;
|
|
20
23
|
}
|
|
21
24
|
export interface IFilesOptions extends IOptions {
|
|
22
25
|
ignore?: string | string[];
|
|
@@ -24,6 +27,8 @@ export interface IFilesOptions extends IOptions {
|
|
|
24
27
|
localPath: string;
|
|
25
28
|
cloudPath?: string;
|
|
26
29
|
}[];
|
|
30
|
+
retryCount?: number;
|
|
31
|
+
retryInterval?: number;
|
|
27
32
|
}
|
|
28
33
|
export interface ICustomOptions {
|
|
29
34
|
bucket: string;
|
|
@@ -87,6 +92,9 @@ export declare class StorageService {
|
|
|
87
92
|
* 上传文件夹
|
|
88
93
|
* @param {string} localPath 本地文件夹路径
|
|
89
94
|
* @param {string} cloudPath 云端文件夹
|
|
95
|
+
* @param {number} parallel 并发量
|
|
96
|
+
* @param {number} retryCount 重试次数
|
|
97
|
+
* @param {number} retryInterval 重试时间间隔(毫秒)
|
|
90
98
|
* @param {(string | string[])} ignore
|
|
91
99
|
* @param {(string | string[])} ignore
|
|
92
100
|
* @returns {Promise<void>}
|
|
@@ -96,6 +104,9 @@ export declare class StorageService {
|
|
|
96
104
|
* 上传文件夹,支持自定义 Region 和 Bucket
|
|
97
105
|
* @param {string} localPath
|
|
98
106
|
* @param {string} cloudPath
|
|
107
|
+
* @param {number} parallel
|
|
108
|
+
* @param {number} retryCount
|
|
109
|
+
* @param {number} retryInterval
|
|
99
110
|
* @param {string} bucket
|
|
100
111
|
* @param {string} region
|
|
101
112
|
* @param {IOptions} options
|
|
@@ -284,5 +295,15 @@ export declare class StorageService {
|
|
|
284
295
|
* 获取存储桶配置
|
|
285
296
|
*/
|
|
286
297
|
private getStorageConfig;
|
|
298
|
+
/**
|
|
299
|
+
* 带重试功能的上传多文件函数
|
|
300
|
+
* @param uploadFiles sdk上传函数
|
|
301
|
+
* @param options sdk上传函数参数
|
|
302
|
+
* @param times 重试次数
|
|
303
|
+
* @param interval 重试时间间隔(毫秒)
|
|
304
|
+
* @param failedFiles 失败文件列表
|
|
305
|
+
* @returns
|
|
306
|
+
*/
|
|
307
|
+
private uploadFilesWithRetry;
|
|
287
308
|
}
|
|
288
309
|
export {};
|
package/.vscode/launch.json
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
// Use IntelliSense to learn about possible attributes.
|
|
3
|
-
// Hover to view descriptions of existing attributes.
|
|
4
|
-
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
-
"version": "0.2.0",
|
|
6
|
-
"configurations": [
|
|
7
|
-
{
|
|
8
|
-
"type": "node",
|
|
9
|
-
"request": "attach",
|
|
10
|
-
"runtime": "node",
|
|
11
|
-
"name": "Cloudbase Debugger For Node",
|
|
12
|
-
"scf": true,
|
|
13
|
-
"port": 9229
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
"type": "node",
|
|
17
|
-
"request": "launch",
|
|
18
|
-
"name": "Launch Program",
|
|
19
|
-
"program": "${workspaceFolder}/lib/index.js",
|
|
20
|
-
"preLaunchTask": "tsc: build - tsconfig.json",
|
|
21
|
-
"outFiles": [
|
|
22
|
-
"${workspaceFolder}/lib/**/*.js"
|
|
23
|
-
]
|
|
24
|
-
}
|
|
25
|
-
]
|
|
26
|
-
}
|
package/.vscode/settings.json
DELETED