Skip to content
This repository was archived by the owner on May 6, 2025. It is now read-only.

Commit f5b4d8e

Browse files
committed
support large file upload & fix sign error
1 parent 630bd33 commit f5b4d8e

20 files changed

Lines changed: 221 additions & 90 deletions

lib/commands/hosting.js

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const commander_1 = __importDefault(require("commander"));
1717
const hosting_1 = require("../hosting");
1818
const error_1 = require("../error");
1919
const utils_1 = require("../utils");
20+
const logger_1 = require("../logger");
2021
const HostingStatusMap = {
2122
init: '初始化中',
2223
process: '处理中',
@@ -39,12 +40,10 @@ commander_1.default
3940
throw new error_1.CloudBaseError('您还没有开启静态网站服务,请先到云开发控制台开启静态网站服务!\n 👉 https://console.cloud.tencent.com/tcb');
4041
}
4142
const url = `https://${website.cdnDomain}`;
42-
if (website.status === 'offline') {
43-
console.log(`静态网站状态:${HostingStatusMap[website.status]}`);
44-
}
45-
else {
46-
console.log(`静态网站域名:${chalk_1.default.bold.underline(url)}\n静态网站状态:${HostingStatusMap[website.status]}`);
43+
if (website.status !== 'offline') {
44+
console.log(`静态网站域名:${chalk_1.default.bold.underline(url)}`);
4745
}
46+
console.log(`静态网站状态:【${HostingStatusMap[website.status]}】`);
4847
}));
4948
commander_1.default
5049
.command('hosting:deploy [filePath] [cloudPath]')
@@ -54,19 +53,21 @@ commander_1.default
5453
const { parent: { configFile }, envId } = options;
5554
const assignEnvId = yield utils_1.getEnvId(envId, configFile);
5655
const isDir = utils_1.isDirectory(filePath);
57-
const loading = utils_1.loadingFactory();
58-
loading.start('文件部署中...');
5956
try {
57+
const onProgress = utils_1.createOnProgressBar(() => {
58+
logger_1.successLog('文件部署成功!');
59+
});
6060
yield hosting_1.hostingDeploy({
6161
filePath,
6262
cloudPath,
6363
envId: assignEnvId,
64-
isDir
64+
isDir,
65+
onProgress
6566
});
66-
loading.succeed('文件部署成功!');
6767
}
68-
catch (error) {
69-
loading.fail('文件部署失败!');
68+
catch (e) {
69+
logger_1.errorLog('文件部署失败!');
70+
console.log(e.message);
7071
}
7172
}));
7273
commander_1.default
@@ -108,7 +109,7 @@ commander_1.default
108109
envId: assignEnvId
109110
});
110111
loading.stop();
111-
const head = ['序号', 'Key', 'LastModified', 'ETag', 'Size(B)'];
112+
const head = ['序号', 'Key', 'LastModified', 'ETag', 'Size(KB)'];
112113
const notDir = item => !(Number(item.Size) === 0 && /\/$/g.test(item.Key));
113114
const tableData = list
114115
.filter(notDir)
@@ -117,7 +118,7 @@ commander_1.default
117118
item.Key,
118119
utils_1.formatDate(item.LastModified, 'yyyy-MM-dd hh:mm:ss'),
119120
item.ETag,
120-
String(item.Size)
121+
String(utils_1.formateFileSize(item.Size, 'KB'))
121122
]);
122123
utils_1.printHorizontalTable(head, tableData);
123124
}

lib/commands/storage.js

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -40,34 +40,37 @@ const AclMap = {
4040
ADMINONLY: '仅管理员可读写'
4141
};
4242
commander_1.default
43-
.command('storage:upload <localPath> <cloudPath>')
44-
.option('-e, --envId', '环境 Id')
43+
.command('storage:upload <localPath> [cloudPath]')
44+
.option('-e, --envId [envId]', '环境 Id')
4545
.description('上传文件/文件夹')
46-
.action(function (localPath, cloudPath, options) {
46+
.action(function (localPath, cloudPath = localPath, options) {
4747
return __awaiter(this, void 0, void 0, function* () {
4848
const { parent: { configFile }, envId } = options;
4949
const assignEnvId = yield utils_1.getEnvId(envId, configFile);
5050
const storageService = yield getStorageService(assignEnvId);
5151
const resolveLocalPath = path_1.default.resolve(localPath);
52+
console.log(resolveLocalPath);
5253
if (!fs_1.default.existsSync(resolveLocalPath)) {
5354
throw new error_1.CloudBaseError('文件未找到!');
5455
}
5556
const isDir = fs_1.default.statSync(resolveLocalPath).isDirectory();
5657
const fileText = isDir ? '文件夹' : '文件';
57-
const loading = utils_1.loadingFactory();
58-
loading.start(`上传${fileText}中`);
58+
const onProgress = utils_1.createOnProgressBar(() => {
59+
logger_1.successLog(`上传${fileText}成功!`);
60+
});
5961
if (isDir) {
60-
yield storageService.uploadDirectory(resolveLocalPath, cloudPath);
62+
yield storageService.uploadDirectory(resolveLocalPath, cloudPath, {
63+
onProgress
64+
});
6165
}
6266
else {
63-
yield storageService.uploadFile(resolveLocalPath, cloudPath);
67+
yield storageService.uploadFile(resolveLocalPath, cloudPath, onProgress);
6468
}
65-
loading.succeed(`上传${fileText}成功!`);
6669
});
6770
});
6871
commander_1.default
6972
.command('storage:download <cloudPath> <localPath>')
70-
.option('-e, --envId', '环境 Id')
73+
.option('-e, --envId [envId]', '环境 Id')
7174
.option('-d, --dir', '下载目标是否为文件夹')
7275
.description('下载文件/文件夹,文件夹需指定 --dir 选项')
7376
.action(function (cloudPath, localPath, options) {
@@ -94,7 +97,7 @@ commander_1.default
9497
});
9598
commander_1.default
9699
.command('storage:delete <cloudPath>')
97-
.option('-e, --envId', '环境 Id')
100+
.option('-e, --envId [envId]', '环境 Id')
98101
.option('-d, --dir', '下载目标是否为文件夹')
99102
.description('删除文件/文件夹,文件夹需指定 --dir 选项')
100103
.action(function (cloudPath, options) {
@@ -117,7 +120,7 @@ commander_1.default
117120
});
118121
commander_1.default
119122
.command('storage:list [cloudPath]')
120-
.option('-e, --envId', '环境 Id')
123+
.option('-e, --envId [envId]', '环境 Id')
121124
.option('--max', '传输数据的最大条数')
122125
.option('--markder', '起始路径名,后(不含)按照 UTF-8 字典序返回条目')
123126
.description('获取文件存储的文件列表')
@@ -127,7 +130,7 @@ commander_1.default
127130
const assignEnvId = yield utils_1.getEnvId(envId, configFile);
128131
const storageService = yield getStorageService(assignEnvId);
129132
const list = yield storageService.listDirectoryFiles(cloudPath);
130-
const head = ['序号', 'Key', 'LastModified', 'ETag', 'Size(B)'];
133+
const head = ['序号', 'Key', 'LastModified', 'ETag', 'Size(KB)'];
131134
const notDir = item => !(Number(item.Size) === 0 && /\/$/g.test(item.Key));
132135
const tableData = list
133136
.filter(notDir)
@@ -136,14 +139,14 @@ commander_1.default
136139
item.Key,
137140
utils_1.formatDate(item.LastModified, 'yyyy-MM-dd hh:mm:ss'),
138141
item.ETag,
139-
String(item.Size)
142+
String(utils_1.formateFileSize(item.Size, 'KB'))
140143
]);
141144
utils_1.printHorizontalTable(head, tableData);
142145
});
143146
});
144147
commander_1.default
145148
.command('storage:url <cloudPath>')
146-
.option('-e, --envId', '环境 Id')
149+
.option('-e, --envId [envId]', '环境 Id')
147150
.description('获取文件临时访问地址')
148151
.action(function (cloudPath, options) {
149152
return __awaiter(this, void 0, void 0, function* () {
@@ -157,7 +160,7 @@ commander_1.default
157160
});
158161
commander_1.default
159162
.command('storage:detail <cloudPath>')
160-
.option('-e, --envId', '环境 Id')
163+
.option('-e, --envId [envId]', '环境 Id')
161164
.description('获取文件信息')
162165
.action(function (cloudPath, options) {
163166
return __awaiter(this, void 0, void 0, function* () {
@@ -173,7 +176,7 @@ commander_1.default
173176
});
174177
commander_1.default
175178
.command('storage:get-acl')
176-
.option('-e, --envId', '环境 Id')
179+
.option('-e, --envId [envId]', '环境 Id')
177180
.description('获取文件存储权限信息')
178181
.action(function (options) {
179182
return __awaiter(this, void 0, void 0, function* () {
@@ -186,7 +189,7 @@ commander_1.default
186189
});
187190
commander_1.default
188191
.command('storage:set-acl')
189-
.option('-e, --envId', '环境 Id')
192+
.option('-e, --envId [envId]', '环境 Id')
190193
.description('设置文件存储权限信息')
191194
.action(function (options) {
192195
return __awaiter(this, void 0, void 0, function* () {

lib/hosting.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ function checkHostingStatus(envId) {
6161
}
6262
const website = hostings.data[0];
6363
if (website.status !== 'online') {
64-
throw new error_1.CloudBaseError(`静态网站服务【${HostingStatusMap[website.status]}】,请稍后重试!`, {
64+
throw new error_1.CloudBaseError(`静态网站服务【${HostingStatusMap[website.status]}】,无法进行此操作!`, {
6565
code: 'INVALID_OPERATION'
6666
});
6767
}
@@ -117,7 +117,7 @@ function destroyHosting(options) {
117117
}
118118
const website = hostings.data[0];
119119
if (website.status !== 'online' && website.status !== 'destroy_fail') {
120-
throw new error_1.CloudBaseError(`静态网站服务【${HostingStatusMap[website.status]}】,无法处理请求!`, {
120+
throw new error_1.CloudBaseError(`静态网站服务【${HostingStatusMap[website.status]}】,无法进行此操作!`, {
121121
code: 'INVALID_OPERATION'
122122
});
123123
}
@@ -134,17 +134,21 @@ function destroyHosting(options) {
134134
exports.destroyHosting = destroyHosting;
135135
function hostingDeploy(options) {
136136
return __awaiter(this, void 0, void 0, function* () {
137-
const { envId, filePath, cloudPath } = options;
137+
const { envId, filePath, cloudPath, onProgress } = options;
138138
const resolvePath = path_1.default.resolve(filePath);
139139
utils_1.checkPathExist(resolvePath, true);
140140
const hosting = yield checkHostingStatus(envId);
141141
const { bucket, regoin } = hosting;
142142
const storageService = yield getStorageService(envId);
143143
if (utils_1.isDirectory(resolvePath)) {
144-
storageService.uploadDirectoryCustom(resolvePath, cloudPath, bucket, regoin);
144+
storageService.uploadDirectoryCustom(resolvePath, cloudPath, bucket, regoin, {
145+
onProgress
146+
});
145147
}
146148
else {
147-
storageService.uploadFileCustom(resolvePath, cloudPath, bucket, regoin);
149+
storageService.uploadFileCustom(resolvePath, cloudPath, bucket, regoin, {
150+
onProgress
151+
});
148152
}
149153
});
150154
}

lib/utils/cloud-api-request.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ function getDate(timestamp) {
5353
const date = new Date(timestamp * 1000);
5454
const year = date.getFullYear();
5555
const month = ('0' + (date.getMonth() + 1)).slice(-2);
56-
const day = ('0' + date.getDate()).slice(-2);
56+
const day = ('0' + date.getUTCDate()).slice(-2);
5757
return `${year}-${month}-${day}`;
5858
}
5959
const ServiceVersionMap = {
@@ -87,7 +87,11 @@ class CloudApiService {
8787
this.data = deepRemoveVoid(Object.assign(Object.assign({}, data), this.baseParams));
8888
this.method = method;
8989
this.url = this.baseUrl;
90-
const { secretId, secretKey, token } = yield auth_1.getCredentialWithoutCheck();
90+
const credential = yield auth_1.getCredentialWithoutCheck();
91+
if (!credential) {
92+
throw new error_1.CloudBaseError('无有效身份信息,请使用 cloudbase login 登录');
93+
}
94+
const { secretId, secretKey, token } = credential;
9195
this.secretId = secretId;
9296
this.secretKey = secretKey;
9397
this.token = token;

lib/utils/fs/index.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,14 @@ function isDirectory(dest) {
2121
return fs_1.default.statSync(dest).isDirectory();
2222
}
2323
exports.isDirectory = isDirectory;
24+
function formateFileSize(size, unit) {
25+
const numSize = Number(size);
26+
const unitMap = {
27+
KB: 1024,
28+
MB: Math.pow(1024, 2),
29+
GB: Math.pow(1024, 3)
30+
};
31+
return Number(numSize / unitMap[unit]).toFixed(2);
32+
}
33+
exports.formateFileSize = formateFileSize;
2434
__export(require("./del"));

lib/utils/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ __export(require("./fs"));
3838
__export(require("./proxy"));
3939
__export(require("./object"));
4040
__export(require("./config"));
41+
__export(require("./progress-bar"));
4142
function zipDir(dirPath, outputPath, ignore) {
4243
return __awaiter(this, void 0, void 0, function* () {
4344
return new Promise((resolve, reject) => {

lib/utils/progress-bar.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"use strict";
2+
var __importDefault = (this && this.__importDefault) || function (mod) {
3+
return (mod && mod.__esModule) ? mod : { "default": mod };
4+
};
5+
Object.defineProperty(exports, "__esModule", { value: true });
6+
const progress_1 = __importDefault(require("progress"));
7+
function createOnProgressBar(onFinished) {
8+
let bar;
9+
let lastLoaded = 0;
10+
let finished = false;
11+
return function (data) {
12+
const { total, loaded, percent } = data;
13+
if (+percent === 1) {
14+
if (finished)
15+
return;
16+
bar.tick(total - lastLoaded);
17+
onFinished();
18+
finished = true;
19+
return;
20+
}
21+
const tick = loaded - lastLoaded;
22+
lastLoaded = loaded;
23+
if (bar) {
24+
bar.tick(tick);
25+
}
26+
else {
27+
bar = new progress_1.default('文件传输中 [:bar] :percent :etas', {
28+
total,
29+
complete: '=',
30+
incomplete: ' ',
31+
width: 50
32+
});
33+
bar.tick(tick);
34+
}
35+
};
36+
}
37+
exports.createOnProgressBar = createOnProgressBar;

package-lock.json

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"author": "",
2626
"license": "ISC",
2727
"dependencies": {
28-
"@cloudbase/manager-node": "^1.2.2",
28+
"@cloudbase/manager-node": "^1.3.0-beta",
2929
"@sentry/node": "^5.7.1",
3030
"address": "^1.1.2",
3131
"archiver": "^3.1.1",
@@ -49,6 +49,7 @@
4949
"open": "^7.0.0",
5050
"ora": "^4.0.2",
5151
"portfinder": "^1.0.20",
52+
"progress": "^2.0.3",
5253
"query-string": "^6.8.1",
5354
"tar-fs": "^2.0.0",
5455
"unzipper": "^0.10.5",

0 commit comments

Comments
 (0)