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

Commit 2723aef

Browse files
committed
[add] support command suggestion
1 parent 5e9075d commit 2723aef

25 files changed

Lines changed: 297 additions & 260 deletions

File tree

bin/cloudbase.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@
22
const os = require('os')
33
const path = require('path')
44
const chalk = require('chalk')
5-
const Sentry = require('@sentry/node')
5+
const address = require('address')
66
const program = require('commander')
7+
const Sentry = require('@sentry/node')
78
const logSymbols = require('log-symbols')
9+
const didYouMean = require('didyoumean')
810
const updateNotifier = require('update-notifier')
9-
const address = require('address')
11+
1012
const pkg = require('../package.json')
1113
const store = require('../lib/utils/store')
12-
const { getProxy } = require('../lib/utils/proxy')
14+
const { ALL_COMMANDS } = require('../lib/constant')
15+
const { getProxy } = require('../lib/utils/tools/proxy')
1316
const { handleCompletion } = require('../lib/completion')
1417

1518
let processArgv = process.argv
@@ -121,6 +124,12 @@ program.version(pkg.version, '-v, --version', '输出当前 CloudBase CLI 版本
121124
// 处理无效命令
122125
program.action(cmd => {
123126
console.log(chalk.bold.red('Error: ') + `${cmd} 不是有效的命令!`)
127+
didYouMean.threshold = 0.5
128+
didYouMean.caseSensitive = false
129+
const suggest = didYouMean(cmd, ALL_COMMANDS)
130+
if (suggest) {
131+
console.log(chalk.bold(`\n您是不是想使用命令:cloudbase ${suggest}\n`))
132+
}
124133
console.log(`使用 ${chalk.bold('cloudbase -h')} 查看所有命令~`)
125134
})
126135

lib/commands/functions/delete.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
1414
Object.defineProperty(exports, "__esModule", { value: true });
1515
const inquirer_1 = __importDefault(require("inquirer"));
1616
const error_1 = require("../../error");
17+
const utils_1 = require("../../utils");
1718
const function_1 = require("../../function");
18-
const logger_1 = require("../../logger");
1919
function deleteFunc(ctx, name) {
2020
return __awaiter(this, void 0, void 0, function* () {
2121
const { envId, config: { functions } } = ctx;
@@ -47,11 +47,13 @@ function deleteFunc(ctx, name) {
4747
envId
4848
});
4949
}
50+
const loading = utils_1.loadingFactory();
51+
loading.start(`删除函数 [${name}] 中...`);
5052
yield function_1.deleteFunction({
5153
envId,
5254
functionName: name
5355
});
54-
logger_1.successLog(`删除函数 [${name}] 成功!`);
56+
loading.succeed(`删除函数 [${name}] 成功!`);
5557
});
5658
}
5759
exports.deleteFunc = deleteFunc;

lib/commands/functions/deploy.js

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,43 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
1414
Object.defineProperty(exports, "__esModule", { value: true });
1515
const path_1 = __importDefault(require("path"));
1616
const inquirer_1 = __importDefault(require("inquirer"));
17-
const utils_1 = require("../../utils");
1817
const error_1 = require("../../error");
1918
const function_1 = require("../../function");
19+
const gateway_1 = require("../../gateway");
20+
const utils_1 = require("../../utils");
21+
const constant_1 = require("../../constant");
2022
function printSuccessTips(envId) {
2123
const link = utils_1.genClickableLink(`https://console.cloud.tencent.com/tcb/scf?envId=${envId}`);
2224
console.log(`\n控制台查看函数详情:${link}`);
23-
console.log(`\n使用 ${utils_1.highlightCommand('cloudbase functions:list')} 命令查看已部署云函数`);
25+
console.log(`\n使用 ${utils_1.highlightCommand('cloudbase functions:list')} 命令查看已部署云函数\n`);
26+
}
27+
function genApiGateway(envId, name) {
28+
var _a, _b, _c, _d;
29+
return __awaiter(this, void 0, void 0, function* () {
30+
const loading = utils_1.loadingFactory();
31+
loading.start('生成云函数 HTTP Service 中...');
32+
const res = yield gateway_1.queryGateway({
33+
name,
34+
envId
35+
});
36+
if (((_a = res) === null || _a === void 0 ? void 0 : _a.EnableService) === false)
37+
return;
38+
let path;
39+
if (((_c = (_b = res) === null || _b === void 0 ? void 0 : _b.APISet) === null || _c === void 0 ? void 0 : _c.length) > 0) {
40+
path = (_d = res.APISet[0]) === null || _d === void 0 ? void 0 : _d.Path;
41+
}
42+
else {
43+
path = `/${utils_1.random(12)}`;
44+
yield gateway_1.createGateway({
45+
envId,
46+
name,
47+
path
48+
});
49+
}
50+
loading.stop();
51+
const link = utils_1.genClickableLink(`https://${envId}.service.tcloudbase.com${path}`);
52+
console.log(`\n云函数 HTTP Service 链接:${link}`);
53+
});
2454
}
2555
function deploy(ctx, name) {
2656
return __awaiter(this, void 0, void 0, function* () {
@@ -68,23 +98,14 @@ function deploy(ctx, name) {
6898
newFunction = functions.find(item => item.name === name);
6999
}
70100
if (!newFunction || !newFunction.name) {
71-
const { useDefaultFunctionDeployOptions } = yield inquirer_1.default.prompt({
101+
const { useDefaultConfig } = yield inquirer_1.default.prompt({
72102
type: 'confirm',
73-
name: 'useDefaultFunctionDeployOptions',
74-
message: '未找到函数发布配置,使用默认配置(仅适用于 Node.js 云函数)',
103+
name: 'useDefaultConfig',
104+
message: '未找到函数发布配置,是否使用默认配置(仅适用于 Node.js 云函数)',
75105
default: false
76106
});
77-
if (useDefaultFunctionDeployOptions) {
78-
newFunction = {
79-
name,
80-
config: {
81-
timeout: 5,
82-
runtime: 'Nodejs8.9',
83-
installDependency: true
84-
},
85-
handler: 'index.main',
86-
ignore: ['node_modules', 'node_modules/**/*', '.git']
87-
};
107+
if (useDefaultConfig) {
108+
newFunction = Object.assign({ name }, constant_1.DefaultFunctionDeployConfig);
88109
}
89110
else {
90111
throw new error_1.CloudBaseError(`函数 ${name} 配置不存在`);
@@ -101,6 +122,7 @@ function deploy(ctx, name) {
101122
functionRootPath
102123
});
103124
loading.succeed(`[${newFunction.name}] 云函数部署成功!`);
125+
yield genApiGateway(envId, name);
104126
printSuccessTips(envId);
105127
}
106128
catch (e) {
@@ -123,6 +145,7 @@ function deploy(ctx, name) {
123145
functionRootPath
124146
});
125147
loading.succeed(`[${newFunction.name}] 云函数部署成功!`);
148+
yield genApiGateway(envId, name);
126149
printSuccessTips(envId);
127150
}
128151
catch (e) {

lib/commands/gateway/create.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ function createService(ctx) {
3434
if (isExisted.length <= 0) {
3535
throw new error_1.CloudBaseError(`[${functionName}] 云函数不存在!`);
3636
}
37-
const res = yield gateway_1.createFunctionGateway({
37+
const res = yield gateway_1.createGateway({
3838
envId,
3939
path: servicePath,
40-
functionName
40+
name: functionName
4141
});
4242
const link = utils_1.genClickableLink(`https://${envId}.service.tcloudbase.com${servicePath}`);
4343
loading.succeed(`云函数 HTTP Service 创建成功!\n点击访问> ${link}`);

lib/completion/index.js

Lines changed: 2 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,65 +4,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
44
};
55
Object.defineProperty(exports, "__esModule", { value: true });
66
const tabtab_1 = __importDefault(require("tabtab"));
7-
const ALL_COMMANDS = [
8-
'login',
9-
'logout',
10-
'init',
11-
'open',
12-
'completion:install',
13-
'completion:uninstall',
14-
'env:list',
15-
'env:rename',
16-
'env:create',
17-
'env:domain:list',
18-
'env:domain:create',
19-
'env:domain:delete',
20-
'env:login:list',
21-
'env:login:create',
22-
'env:login:update',
23-
'functions:list',
24-
'functions:download',
25-
'functions:deploy',
26-
'functions:delete',
27-
'functions:detail',
28-
'functions:code:update',
29-
'functions:config:update',
30-
'functions:copy',
31-
'functions:log',
32-
'functions:trigger:create',
33-
'functions:trigger:delete',
34-
'functions:invoke',
35-
'functions:run',
36-
'storage:upload',
37-
'storage:download',
38-
'storage:delete',
39-
'storage:list',
40-
'storage:url',
41-
'storage:detail',
42-
'storage:get-acl',
43-
'storage:set-acl',
44-
'hosting:detail',
45-
'hosting:deploy',
46-
'hosting:delete',
47-
'hosting:list',
48-
'server:deploy',
49-
'server:log',
50-
'server:reload',
51-
'server:stop',
52-
'server:show',
53-
'service:create',
54-
'service:delete',
55-
'service:list',
56-
'service:domain:bind',
57-
'service:domain:unbind',
58-
'service:domain:list'
59-
];
7+
const constant_1 = require("../constant");
608
const completion = env => {
619
if (!env.complete)
6210
return;
6311
const args = process.argv.slice(5);
6412
const cmd = args[0];
65-
const commands = ALL_COMMANDS.filter(item => item.indexOf(cmd) > -1);
13+
const commands = constant_1.ALL_COMMANDS.filter(item => item.indexOf(cmd) > -1);
6614
if (commands.length > 0) {
6715
return tabtab_1.default.log(commands);
6816
}

lib/constant.js

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,67 @@ class ConfigItems {
55
exports.ConfigItems = ConfigItems;
66
ConfigItems.credentail = 'credential';
77
ConfigItems.ssh = 'ssh';
8-
exports.defaultFunctionDeployOptions = {
9-
config: {
10-
timeout: 5,
11-
runtime: 'Nodejs8.9'
12-
},
13-
handler: 'index.main'
8+
exports.DefaultFunctionDeployConfig = {
9+
timeout: 3,
10+
runtime: 'Nodejs8.9',
11+
handler: 'index.main',
12+
installDependency: true,
13+
ignore: ['node_modules', 'node_modules/**/*', '.git']
1414
};
1515
exports.DefaultCloudBaseConfig = {
1616
functionRoot: './functions',
1717
functions: []
1818
};
19+
exports.ALL_COMMANDS = [
20+
'login',
21+
'logout',
22+
'init',
23+
'open',
24+
'completion:install',
25+
'completion:uninstall',
26+
'env:list',
27+
'env:rename',
28+
'env:create',
29+
'env:domain:list',
30+
'env:domain:create',
31+
'env:domain:delete',
32+
'env:login:list',
33+
'env:login:create',
34+
'env:login:update',
35+
'functions:list',
36+
'functions:download',
37+
'functions:deploy',
38+
'functions:delete',
39+
'functions:detail',
40+
'functions:code:update',
41+
'functions:config:update',
42+
'functions:copy',
43+
'functions:log',
44+
'functions:trigger:create',
45+
'functions:trigger:delete',
46+
'functions:invoke',
47+
'functions:run',
48+
'storage:upload',
49+
'storage:download',
50+
'storage:delete',
51+
'storage:list',
52+
'storage:url',
53+
'storage:detail',
54+
'storage:get-acl',
55+
'storage:set-acl',
56+
'hosting:detail',
57+
'hosting:deploy',
58+
'hosting:delete',
59+
'hosting:list',
60+
'server:deploy',
61+
'server:log',
62+
'server:reload',
63+
'server:stop',
64+
'server:show',
65+
'service:create',
66+
'service:delete',
67+
'service:list',
68+
'service:domain:bind',
69+
'service:domain:unbind',
70+
'service:domain:list'
71+
];

lib/function/create.js

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
1111
Object.defineProperty(exports, "__esModule", { value: true });
1212
const utils_1 = require("../utils");
1313
const error_1 = require("../error");
14-
const trigger_1 = require("./trigger");
1514
const base_1 = require("./base");
16-
function retryCreateTrigger(options, count = 0) {
17-
return __awaiter(this, void 0, void 0, function* () {
18-
try {
19-
yield trigger_1.createFunctionTriggers(options);
20-
}
21-
catch (e) {
22-
if (count < 3) {
23-
yield utils_1.sleep(500);
24-
yield retryCreateTrigger(options, count + 1);
25-
}
26-
else {
27-
throw e;
28-
}
29-
}
30-
});
31-
}
3215
function createFunction(options) {
3316
var _a, _b;
3417
return __awaiter(this, void 0, void 0, function* () {

lib/function/delete.js

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,28 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
99
});
1010
};
1111
Object.defineProperty(exports, "__esModule", { value: true });
12-
const utils_1 = require("../utils");
1312
const logger_1 = require("../logger");
1413
const error_1 = require("../error");
14+
const utils_1 = require("../utils");
15+
const gateway_1 = require("../gateway");
1516
const scfService = new utils_1.CloudApiService('scf');
1617
function deleteFunction({ functionName, envId }) {
18+
var _a, _b;
1719
return __awaiter(this, void 0, void 0, function* () {
18-
try {
19-
yield scfService.request('DeleteFunction', {
20-
FunctionName: functionName,
21-
Namespace: envId
20+
const res = yield gateway_1.queryGateway({
21+
envId,
22+
name: functionName
23+
});
24+
if (((_b = (_a = res) === null || _a === void 0 ? void 0 : _a.APISet) === null || _b === void 0 ? void 0 : _b.length) > 0) {
25+
yield gateway_1.deleteGateway({
26+
envId,
27+
name: functionName
2228
});
2329
}
24-
catch (e) {
25-
throw new error_1.CloudBaseError(`[${functionName}] 删除操作失败:${e.message}!`);
26-
}
30+
yield scfService.request('DeleteFunction', {
31+
FunctionName: functionName,
32+
Namespace: envId
33+
});
2734
});
2835
}
2936
exports.deleteFunction = deleteFunction;

0 commit comments

Comments
 (0)