@cloudbase/cli 1.9.8-beta → 1.10.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/package.json +6 -4
- package/src/commands/common.ts +14 -6
- package/src/commands/functions/alias/getRoute.ts +76 -0
- package/src/commands/functions/alias/index.ts +2 -0
- package/src/commands/functions/alias/setRoute.ts +82 -0
- package/src/commands/functions/concurrency/delete.ts +45 -0
- package/src/commands/functions/concurrency/index.ts +3 -0
- package/src/commands/functions/concurrency/list.ts +58 -0
- package/src/commands/functions/concurrency/set.ts +47 -0
- package/src/commands/functions/index.ts +3 -0
- package/src/commands/functions/list.ts +1 -8
- package/src/commands/functions/version/index.ts +2 -0
- package/src/commands/functions/version/list.ts +73 -0
- package/src/commands/functions/version/publish.ts +43 -0
- package/src/commands/lowcode/comps.ts +91 -2
- package/src/constant.ts +24 -0
- package/src/function/alias.ts +43 -0
- package/src/function/concurrency.ts +57 -0
- package/src/function/index.ts +4 -1
- package/src/function/version.ts +39 -0
- package/src/types.ts +95 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudbase/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "cli tool for cloudbase",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -26,15 +26,15 @@
|
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@cloudbase/cloud-api": "^0.4.0",
|
|
28
28
|
"@cloudbase/framework-core": "^1.6.1",
|
|
29
|
-
"@cloudbase/lowcode-cli": "^0.12.
|
|
30
|
-
"@cloudbase/manager-node": "3.
|
|
29
|
+
"@cloudbase/lowcode-cli": "^0.12.2",
|
|
30
|
+
"@cloudbase/manager-node": "3.12.0",
|
|
31
31
|
"@cloudbase/toolbox": "^0.7.2",
|
|
32
32
|
"@sentry/node": "^5.10.2",
|
|
33
33
|
"address": "^1.1.2",
|
|
34
34
|
"axios": "^0.21.1",
|
|
35
35
|
"chalk": "^2.4.2",
|
|
36
36
|
"cli-table3": "^0.5.1",
|
|
37
|
-
"commander": "
|
|
37
|
+
"commander": "7",
|
|
38
38
|
"del": "^5.1.0",
|
|
39
39
|
"didyoumean": "^1.2.1",
|
|
40
40
|
"enquirer": "^2.3.6",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"progress": "^2.0.3",
|
|
54
54
|
"query-string": "^6.8.1",
|
|
55
55
|
"reflect-metadata": "^0.1.13",
|
|
56
|
+
"semver": "^7.3.5",
|
|
56
57
|
"tar-fs": "^2.0.1",
|
|
57
58
|
"terminal-link": "^2.1.1",
|
|
58
59
|
"unzipper": "^0.10.10",
|
|
@@ -66,6 +67,7 @@
|
|
|
66
67
|
"@types/lodash": "^4.14.149",
|
|
67
68
|
"@types/node": "^12.12.38",
|
|
68
69
|
"@types/node-fetch": "^2.5.4",
|
|
70
|
+
"@types/semver": "^7.3.9",
|
|
69
71
|
"@types/webpack-dev-server": "^3.11.1",
|
|
70
72
|
"@typescript-eslint/eslint-plugin": "^4.8.1",
|
|
71
73
|
"@typescript-eslint/parser": "^4.8.1",
|
package/src/commands/common.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import chalk from 'chalk'
|
|
2
2
|
import * as Sentry from '@sentry/node'
|
|
3
3
|
import { EventEmitter } from 'events'
|
|
4
|
-
import { program, Command as Commander } from 'commander'
|
|
4
|
+
import { program, Command as Commander, Option } from 'commander'
|
|
5
5
|
import { CloudBaseError } from '../error'
|
|
6
6
|
import { ICommandContext } from '../types'
|
|
7
7
|
import {
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
interface ICommandOption {
|
|
17
17
|
flags: string
|
|
18
18
|
desc: string
|
|
19
|
+
hideHelp?: boolean
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
export interface ICommandOptions {
|
|
@@ -87,6 +88,7 @@ export abstract class Command extends EventEmitter {
|
|
|
87
88
|
} else {
|
|
88
89
|
// 新命令或原有的旧命令格式
|
|
89
90
|
instance = program.command(cmd) as Commander
|
|
91
|
+
// @ts-expect-error 这里是用来自定义commander fallback 帮助信息
|
|
90
92
|
instance._helpDescription = '输出帮助信息'
|
|
91
93
|
instance.addHelpCommand('help [command]', '查看命令帮助信息')
|
|
92
94
|
cmdMap.set(cmd, instance)
|
|
@@ -110,6 +112,7 @@ export abstract class Command extends EventEmitter {
|
|
|
110
112
|
instance = cmdMap.get(cmdKey)
|
|
111
113
|
} else {
|
|
112
114
|
instance = instance.command(cmdName) as Commander
|
|
115
|
+
// @ts-expect-error 这里是用来自定义commander fallback 帮助信息
|
|
113
116
|
instance._helpDescription = '查看命令帮助信息'
|
|
114
117
|
desc && instance.description(desc)
|
|
115
118
|
cmdMap.set(cmdKey, instance)
|
|
@@ -137,11 +140,16 @@ export abstract class Command extends EventEmitter {
|
|
|
137
140
|
|
|
138
141
|
private createProgram(instance: Commander, deprecate: boolean, newCmd?: string) {
|
|
139
142
|
const { cmd, desc, options, requiredEnvId = true, withoutAuth = false } = this.options
|
|
140
|
-
|
|
141
|
-
instance.storeOptionsAsProperties(false).passCommandToAction(false)
|
|
142
|
-
|
|
143
|
+
instance.storeOptionsAsProperties(false)
|
|
143
144
|
options.forEach((option) => {
|
|
144
|
-
|
|
145
|
+
|
|
146
|
+
const { hideHelp } = option
|
|
147
|
+
if(hideHelp) {
|
|
148
|
+
instance.addOption(new Option(option.flags, option.desc).hideHelp())
|
|
149
|
+
} else {
|
|
150
|
+
instance.option(option.flags, option.desc)
|
|
151
|
+
}
|
|
152
|
+
|
|
145
153
|
})
|
|
146
154
|
|
|
147
155
|
instance.description(desc)
|
|
@@ -178,7 +186,7 @@ export abstract class Command extends EventEmitter {
|
|
|
178
186
|
}
|
|
179
187
|
|
|
180
188
|
// 处理前
|
|
181
|
-
this.emit('preHandle', ctx, args)
|
|
189
|
+
this.emit('preHandle', ctx, args.slice(0, -1))
|
|
182
190
|
await this.preHandle()
|
|
183
191
|
|
|
184
192
|
// 废弃警告
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
|
|
2
|
+
import { Command, ICommand } from '../../common'
|
|
3
|
+
import { loadingFactory, printHorizontalTable } from '../../../utils'
|
|
4
|
+
import { getFunctionAliasConfig } from '../../../function'
|
|
5
|
+
import { InjectParams, CmdContext, ArgsParams, ArgsOptions } from '../../../decorators'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
function parseRoutingConfigValue(expression: string) {
|
|
9
|
+
const commaIndex = expression.indexOf(',')
|
|
10
|
+
const valueExpression = expression.substring(commaIndex + 1, expression.length - 1)
|
|
11
|
+
return valueExpression
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
@ICommand()
|
|
15
|
+
export class getFunctionRoutingConfig extends Command {
|
|
16
|
+
get options() {
|
|
17
|
+
return {
|
|
18
|
+
cmd: 'fn',
|
|
19
|
+
childCmd: 'get-route <name>',
|
|
20
|
+
options: [
|
|
21
|
+
{
|
|
22
|
+
flags: '-e, --envId <envId>',
|
|
23
|
+
desc: '环境 Id'
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
desc: '查看函数版本流量配置'
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@InjectParams()
|
|
31
|
+
async execute(@CmdContext() ctx, @ArgsParams() params) {
|
|
32
|
+
const name = params?.[0]
|
|
33
|
+
|
|
34
|
+
const {
|
|
35
|
+
envId
|
|
36
|
+
} = ctx
|
|
37
|
+
|
|
38
|
+
const loading = loadingFactory()
|
|
39
|
+
loading.start(`查询函数 [${name}] 版本流量配置中...`)
|
|
40
|
+
|
|
41
|
+
const aliasRes = await getFunctionAliasConfig({
|
|
42
|
+
envId,
|
|
43
|
+
functionName: name,
|
|
44
|
+
name: '$DEFAULT'
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
const routingConfig = aliasRes?.RoutingConfig?.AddtionVersionMatchs
|
|
48
|
+
let finalConfig = []
|
|
49
|
+
if (routingConfig.length === 1) {
|
|
50
|
+
finalConfig.push({
|
|
51
|
+
version: routingConfig[0].Version,
|
|
52
|
+
value: parseRoutingConfigValue(routingConfig[0].Expression)
|
|
53
|
+
})
|
|
54
|
+
} else if (routingConfig.length === 2) {
|
|
55
|
+
finalConfig.push({
|
|
56
|
+
version: routingConfig[0].Version,
|
|
57
|
+
value: parseRoutingConfigValue(routingConfig[0].Expression)
|
|
58
|
+
}, {
|
|
59
|
+
version: routingConfig[1].Version,
|
|
60
|
+
value: 100 - Number(parseRoutingConfigValue(routingConfig[0].Expression))
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
loading.stop()
|
|
65
|
+
|
|
66
|
+
const head: string[] = ['版本', '流量比例']
|
|
67
|
+
|
|
68
|
+
const tableData = finalConfig.map((item) => [
|
|
69
|
+
item.version,
|
|
70
|
+
item.value
|
|
71
|
+
])
|
|
72
|
+
|
|
73
|
+
printHorizontalTable(head, tableData)
|
|
74
|
+
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
|
|
2
|
+
import { Command, ICommand } from '../../common'
|
|
3
|
+
import { CloudBaseError } from '../../../error'
|
|
4
|
+
import { loadingFactory } from '../../../utils'
|
|
5
|
+
import { setFunctionAliasConfig } from '../../../function'
|
|
6
|
+
import { InjectParams, CmdContext, ArgsParams, ArgsOptions } from '../../../decorators'
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@ICommand()
|
|
10
|
+
export class setFunctionRoutingConfig extends Command {
|
|
11
|
+
get options() {
|
|
12
|
+
return {
|
|
13
|
+
cmd: 'fn',
|
|
14
|
+
childCmd: 'config-route <name> <version1> <traffic1> [version2] [traffic2]',
|
|
15
|
+
options: [
|
|
16
|
+
{
|
|
17
|
+
flags: '-e, --envId <envId>',
|
|
18
|
+
desc: '环境 Id'
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
desc: '设置函数版本流量配置'
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@InjectParams()
|
|
26
|
+
async execute(@CmdContext() ctx, @ArgsParams() params) {
|
|
27
|
+
const name = params?.[0]
|
|
28
|
+
const version1 = params?.[1]
|
|
29
|
+
const traffic1 = Number(params?.[2])
|
|
30
|
+
|
|
31
|
+
const version2 = params?.[3]
|
|
32
|
+
const traffic2 = Number(params?.[4])
|
|
33
|
+
|
|
34
|
+
// 校验
|
|
35
|
+
|
|
36
|
+
// 1. version2 及 traffic2 必须同时存在
|
|
37
|
+
if ((version2 === undefined && traffic2 !== undefined) || (version2 !== undefined && traffic2 === undefined)) {
|
|
38
|
+
throw new CloudBaseError('version2 和 traffic2 必须同时设置')
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (traffic1 !== undefined && traffic2 !== undefined) {
|
|
42
|
+
if (traffic1 + traffic2 !== 100) {
|
|
43
|
+
throw new CloudBaseError('traffic1 和 traffic2 同时设置时,需保证总和 100')
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const {
|
|
48
|
+
envId
|
|
49
|
+
} = ctx
|
|
50
|
+
|
|
51
|
+
const loading = loadingFactory()
|
|
52
|
+
loading.start(`设置函数 [${name}] 版本流量配置中...`)
|
|
53
|
+
|
|
54
|
+
let routingConfigParams = {
|
|
55
|
+
AddtionVersionMatchs: [{
|
|
56
|
+
Expression: `[0,${traffic1})`,
|
|
57
|
+
Key: "invoke.headers.X-Tcb-Route-Key",
|
|
58
|
+
Method: "range",
|
|
59
|
+
Version: version1
|
|
60
|
+
}]
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (version2 !== undefined) {
|
|
64
|
+
routingConfigParams.AddtionVersionMatchs.push({
|
|
65
|
+
Expression: `[${traffic1},${100})`,
|
|
66
|
+
Key: "invoke.headers.X-Tcb-Route-Key",
|
|
67
|
+
Method: "range",
|
|
68
|
+
Version: version2
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
await setFunctionAliasConfig({
|
|
73
|
+
envId,
|
|
74
|
+
functionName: name,
|
|
75
|
+
name: '$DEFAULT',
|
|
76
|
+
functionVersion: '$LATEST',
|
|
77
|
+
routingConfig: routingConfigParams
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
loading.succeed(`设置函数 [${name}] 版本流量配置成功!`)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
|
|
2
|
+
import { Command, ICommand } from '../../common'
|
|
3
|
+
import { CloudBaseError } from '../../../error'
|
|
4
|
+
import { loadingFactory } from '../../../utils'
|
|
5
|
+
import { deleteProvisionedConcurrencyConfig } from '../../../function'
|
|
6
|
+
import { InjectParams, CmdContext, ArgsParams, ArgsOptions } from '../../../decorators'
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@ICommand()
|
|
10
|
+
export class deleteProvisionedConcurrency extends Command {
|
|
11
|
+
get options() {
|
|
12
|
+
return {
|
|
13
|
+
cmd: 'fn',
|
|
14
|
+
childCmd: 'delete-provisioned-concurrency <name> <version>',
|
|
15
|
+
options: [
|
|
16
|
+
{
|
|
17
|
+
flags: '-e, --envId <envId>',
|
|
18
|
+
desc: '环境 Id'
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
desc: '删除函数版本预置并发配置'
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@InjectParams()
|
|
26
|
+
async execute(@CmdContext() ctx, @ArgsParams() params) {
|
|
27
|
+
const name = params?.[0]
|
|
28
|
+
const version = params?.[1]
|
|
29
|
+
|
|
30
|
+
const {
|
|
31
|
+
envId
|
|
32
|
+
} = ctx
|
|
33
|
+
|
|
34
|
+
const loading = loadingFactory()
|
|
35
|
+
loading.start(`删除函数 [${name}] 预置并发配置中...`)
|
|
36
|
+
|
|
37
|
+
await deleteProvisionedConcurrencyConfig({
|
|
38
|
+
envId,
|
|
39
|
+
functionName: name,
|
|
40
|
+
qualifier: version
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
loading.succeed(`删除函数 [${name}] 预置并发配置成功!`)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
|
|
2
|
+
import { Command, ICommand } from '../../common'
|
|
3
|
+
import { CloudBaseError } from '../../../error'
|
|
4
|
+
import { loadingFactory, printHorizontalTable } from '../../../utils'
|
|
5
|
+
import { getProvisionedConcurrencyConfig } from '../../../function'
|
|
6
|
+
import { InjectParams, CmdContext, ArgsParams, ArgsOptions } from '../../../decorators'
|
|
7
|
+
import { StatusMap, ConcurrencyTaskStatus } from '../../../constant'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@ICommand()
|
|
11
|
+
export class getProvisionedConcurrency extends Command {
|
|
12
|
+
get options() {
|
|
13
|
+
return {
|
|
14
|
+
cmd: 'fn',
|
|
15
|
+
childCmd: 'get-provisioned-concurrency <name> [version]',
|
|
16
|
+
options: [
|
|
17
|
+
{
|
|
18
|
+
flags: '-e, --envId <envId>',
|
|
19
|
+
desc: '环境 Id'
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
desc: '获取函数版本预置并发配置'
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@InjectParams()
|
|
27
|
+
async execute(@CmdContext() ctx, @ArgsParams() params, @ArgsOptions() options) {
|
|
28
|
+
const name = params?.[0]
|
|
29
|
+
const version = params?.[1]
|
|
30
|
+
|
|
31
|
+
const {
|
|
32
|
+
envId
|
|
33
|
+
} = ctx
|
|
34
|
+
|
|
35
|
+
const loading = loadingFactory()
|
|
36
|
+
loading.start(`拉取函数 [${name}] 预置并发配置中...`)
|
|
37
|
+
|
|
38
|
+
const res = await getProvisionedConcurrencyConfig({
|
|
39
|
+
envId,
|
|
40
|
+
functionName: name,
|
|
41
|
+
qualifier: version
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
loading.stop()
|
|
45
|
+
|
|
46
|
+
const head: string[] = ['设置并发数', '已完成并发数', '预置任务状态', '状态说明', '版本号']
|
|
47
|
+
|
|
48
|
+
const tableData = res.Allocated.map((item) => [
|
|
49
|
+
item.AllocatedProvisionedConcurrencyNum,
|
|
50
|
+
item.AvailableProvisionedConcurrencyNum,
|
|
51
|
+
ConcurrencyTaskStatus[item.Status] || '无',
|
|
52
|
+
item.StatusReason,
|
|
53
|
+
item.Qualifier
|
|
54
|
+
])
|
|
55
|
+
|
|
56
|
+
printHorizontalTable(head, tableData)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
|
|
2
|
+
import { Command, ICommand } from '../../common'
|
|
3
|
+
import { CloudBaseError } from '../../../error'
|
|
4
|
+
import { loadingFactory } from '../../../utils'
|
|
5
|
+
import { setProvisionedConcurrencyConfig } from '../../../function'
|
|
6
|
+
import { InjectParams, CmdContext, ArgsParams, ArgsOptions } from '../../../decorators'
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@ICommand()
|
|
10
|
+
export class setProvisionedConcurrency extends Command {
|
|
11
|
+
get options() {
|
|
12
|
+
return {
|
|
13
|
+
cmd: 'fn',
|
|
14
|
+
childCmd: 'set-provisioned-concurrency <name> <version> <concurrency>',
|
|
15
|
+
options: [
|
|
16
|
+
{
|
|
17
|
+
flags: '-e, --envId <envId>',
|
|
18
|
+
desc: '环境 Id'
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
desc: '设置函数版本预置并发'
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@InjectParams()
|
|
26
|
+
async execute(@CmdContext() ctx, @ArgsParams() params) {
|
|
27
|
+
const name = params?.[0]
|
|
28
|
+
const version = params?.[1]
|
|
29
|
+
const concurrency = Number(params?.[2] || 0)
|
|
30
|
+
|
|
31
|
+
const {
|
|
32
|
+
envId
|
|
33
|
+
} = ctx
|
|
34
|
+
|
|
35
|
+
const loading = loadingFactory()
|
|
36
|
+
loading.start(`配置函数 [${name}] 预置并发中...`)
|
|
37
|
+
|
|
38
|
+
await setProvisionedConcurrencyConfig({
|
|
39
|
+
envId,
|
|
40
|
+
functionName: name,
|
|
41
|
+
qualifier: version,
|
|
42
|
+
versionProvisionedConcurrencyNum: concurrency
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
loading.succeed(`配置函数 [${name}] 预置并发成功!`)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -3,14 +3,7 @@ import { CloudBaseError } from '../../error'
|
|
|
3
3
|
import { listFunction } from '../../function'
|
|
4
4
|
import { printHorizontalTable, loadingFactory } from '../../utils'
|
|
5
5
|
import { InjectParams, EnvId, ArgsOptions } from '../../decorators'
|
|
6
|
-
|
|
7
|
-
const StatusMap = {
|
|
8
|
-
Active: '部署完成',
|
|
9
|
-
Creating: '创建中',
|
|
10
|
-
CreateFailed: '创建失败',
|
|
11
|
-
Updating: '更新中',
|
|
12
|
-
UpdateFailed: '更新失败'
|
|
13
|
-
}
|
|
6
|
+
import { StatusMap } from '../../constant'
|
|
14
7
|
|
|
15
8
|
@ICommand()
|
|
16
9
|
export class ListFunction extends Command {
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
|
|
2
|
+
import { Command, ICommand } from '../../common'
|
|
3
|
+
import { CloudBaseError } from '../../../error'
|
|
4
|
+
import { loadingFactory, printHorizontalTable } from '../../../utils'
|
|
5
|
+
import { listFunctionVersions } from '../../../function'
|
|
6
|
+
import { InjectParams, CmdContext, ArgsParams, ArgsOptions } from '../../../decorators'
|
|
7
|
+
import { StatusMap } from '../../../constant'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@ICommand()
|
|
11
|
+
export class ListFunctionVersion extends Command {
|
|
12
|
+
get options() {
|
|
13
|
+
return {
|
|
14
|
+
cmd: 'fn',
|
|
15
|
+
childCmd: 'list-function-versions <name>',
|
|
16
|
+
options: [
|
|
17
|
+
{
|
|
18
|
+
flags: '-e, --envId <envId>',
|
|
19
|
+
desc: '环境 Id'
|
|
20
|
+
},
|
|
21
|
+
{ flags: '-l, --limit <limit>', desc: '返回数据长度,默认值为 20' },
|
|
22
|
+
{
|
|
23
|
+
flags: '-o, --offset <offset>',
|
|
24
|
+
desc: '数据偏移量,默认值为 0'
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
desc: '展示函数版本列表'
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@InjectParams()
|
|
32
|
+
async execute(@CmdContext() ctx, @ArgsParams() params, @ArgsOptions() options) {
|
|
33
|
+
const name = params?.[0]
|
|
34
|
+
let { limit = 20, offset = 0 } = options
|
|
35
|
+
limit = Number(limit)
|
|
36
|
+
offset = Number(offset)
|
|
37
|
+
if (!Number.isInteger(limit) || !Number.isInteger(offset)) {
|
|
38
|
+
throw new CloudBaseError('limit 和 offset 必须为整数')
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (limit < 0 || offset < 0) {
|
|
42
|
+
throw new CloudBaseError('limit 和 offset 必须为大于 0 的整数')
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const {
|
|
46
|
+
envId
|
|
47
|
+
} = ctx
|
|
48
|
+
|
|
49
|
+
const loading = loadingFactory()
|
|
50
|
+
loading.start(`拉取函数 [${name}] 版本列表中...`)
|
|
51
|
+
|
|
52
|
+
const res = await listFunctionVersions({
|
|
53
|
+
envId,
|
|
54
|
+
functionName: name,
|
|
55
|
+
offset,
|
|
56
|
+
limit
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
loading.stop()
|
|
60
|
+
|
|
61
|
+
const head: string[] = ['版本', '描述', '创建时间', '修改时间', '状态']
|
|
62
|
+
|
|
63
|
+
const tableData = res.Versions.map((item) => [
|
|
64
|
+
item.Version,
|
|
65
|
+
item.Description,
|
|
66
|
+
item.AddTime,
|
|
67
|
+
item.ModTime,
|
|
68
|
+
StatusMap[item.Status]
|
|
69
|
+
])
|
|
70
|
+
|
|
71
|
+
printHorizontalTable(head, tableData)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
|
|
2
|
+
import { Command, ICommand } from '../../common'
|
|
3
|
+
import { CloudBaseError } from '../../../error'
|
|
4
|
+
import { loadingFactory } from '../../../utils'
|
|
5
|
+
import { publishVersion } from '../../../function'
|
|
6
|
+
import { InjectParams, CmdContext, ArgsParams } from '../../../decorators'
|
|
7
|
+
|
|
8
|
+
@ICommand()
|
|
9
|
+
export class PublishFunctionVersion extends Command {
|
|
10
|
+
get options() {
|
|
11
|
+
return {
|
|
12
|
+
cmd: 'fn',
|
|
13
|
+
childCmd: 'publish-version <name> [description]',
|
|
14
|
+
options: [
|
|
15
|
+
{
|
|
16
|
+
flags: '-e, --envId <envId>',
|
|
17
|
+
desc: '环境 Id'
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
desc: '发布函数新版本'
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@InjectParams()
|
|
25
|
+
async execute(@CmdContext() ctx, @ArgsParams() params) {
|
|
26
|
+
const name = params?.[0]
|
|
27
|
+
const description = params?.[1]
|
|
28
|
+
const {
|
|
29
|
+
envId
|
|
30
|
+
} = ctx
|
|
31
|
+
|
|
32
|
+
const loading = loadingFactory()
|
|
33
|
+
loading.start(`发布函数 [${name}] 新版本中...`)
|
|
34
|
+
|
|
35
|
+
await publishVersion({
|
|
36
|
+
envId,
|
|
37
|
+
functionName: name,
|
|
38
|
+
description
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
loading.succeed(`发布函数 [${name}] 新版本成功!`)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -14,11 +14,13 @@ import {
|
|
|
14
14
|
graceDebugComps,
|
|
15
15
|
gracePublishComps,
|
|
16
16
|
IPublishCompsInfo,
|
|
17
|
+
publishVersion
|
|
17
18
|
} from '@cloudbase/lowcode-cli'
|
|
18
19
|
import { exec } from 'child_process'
|
|
19
20
|
import { prompt } from 'enquirer'
|
|
20
21
|
import fse from 'fs-extra'
|
|
21
22
|
import { promisify } from 'util'
|
|
23
|
+
import * as semver from 'semver'
|
|
22
24
|
|
|
23
25
|
const cloudService = CloudApiService.getInstance('lowcode')
|
|
24
26
|
const DEFAULE_TEMPLATE_PATH = 'https://comp-public-1303824488.cos.ap-shanghai.myqcloud.com/lcc/template.zip'
|
|
@@ -176,6 +178,11 @@ export class LowCodePublishComps extends Command {
|
|
|
176
178
|
{
|
|
177
179
|
flags: '--verbose',
|
|
178
180
|
desc: '是否打印详细日志'
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
flags: '--admin',
|
|
184
|
+
desc: '是否使用admin接口',
|
|
185
|
+
hideHelp: true
|
|
179
186
|
}
|
|
180
187
|
],
|
|
181
188
|
desc: '发布组件库',
|
|
@@ -184,14 +191,16 @@ export class LowCodePublishComps extends Command {
|
|
|
184
191
|
}
|
|
185
192
|
|
|
186
193
|
@InjectParams()
|
|
187
|
-
async execute(@CmdContext() ctx, @Log() log
|
|
194
|
+
async execute(@CmdContext() ctx, @Log() log: Logger, @ArgsOptions() options: any) {
|
|
188
195
|
// 有RC配置, 使用新接口
|
|
196
|
+
|
|
189
197
|
const config = ctx.config.lowcodeCustomComponents
|
|
190
198
|
if (config) {
|
|
191
199
|
await gracePublishComps({
|
|
192
200
|
...config,
|
|
193
201
|
context: config.context || process.cwd(),
|
|
194
|
-
logger: log
|
|
202
|
+
logger: log,
|
|
203
|
+
isAdmin: Boolean(options.admin)
|
|
195
204
|
})
|
|
196
205
|
log.success('组件库 - 已同步到云端,请到低码控制台发布该组件库!')
|
|
197
206
|
return
|
|
@@ -224,6 +233,86 @@ export class LowCodePublishComps extends Command {
|
|
|
224
233
|
}
|
|
225
234
|
}
|
|
226
235
|
|
|
236
|
+
@ICommand()
|
|
237
|
+
export class LowCodePublishVersionComps extends Command {
|
|
238
|
+
get options() {
|
|
239
|
+
return {
|
|
240
|
+
cmd: 'lowcode',
|
|
241
|
+
childCmd: 'publishVersion',
|
|
242
|
+
options: [
|
|
243
|
+
{
|
|
244
|
+
flags: '--verbose',
|
|
245
|
+
desc: '是否打印详细日志'
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
flags: '--comment <comment>',
|
|
249
|
+
desc: '版本备注',
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
flags: '--tag <version>',
|
|
253
|
+
desc: '版本号'
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
flags: '--admin',
|
|
257
|
+
desc: '是否使用admin接口',
|
|
258
|
+
hideHelp: true
|
|
259
|
+
}
|
|
260
|
+
],
|
|
261
|
+
desc: '发布组件库版本',
|
|
262
|
+
requiredEnvId: false
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
@InjectParams()
|
|
267
|
+
async execute(@CmdContext() ctx, @ArgsOptions() options, @Log() log?: Logger) {
|
|
268
|
+
// 有RC配置, 使用新接口
|
|
269
|
+
const {tag, comment, admin} = options
|
|
270
|
+
if(!comment) {
|
|
271
|
+
log.error('请使用 --comment 填写版本注释')
|
|
272
|
+
return
|
|
273
|
+
}
|
|
274
|
+
if(!tag) {
|
|
275
|
+
log.error('请使用 --tag 填写符合semver的版本号')
|
|
276
|
+
return
|
|
277
|
+
}
|
|
278
|
+
if(!semver.valid(tag)) {
|
|
279
|
+
log.error('组件库版本不符合semver标准')
|
|
280
|
+
return
|
|
281
|
+
}
|
|
282
|
+
const config = ctx.config.lowcodeCustomComponents
|
|
283
|
+
|
|
284
|
+
if(!config) {
|
|
285
|
+
log.error('组件库 - 请添加组件库配置到cloudbaserc.json 以使用该命令')
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const res = await publishVersion({
|
|
289
|
+
...config,
|
|
290
|
+
context: config.context || process.cwd(),
|
|
291
|
+
logger: log,
|
|
292
|
+
isAdmin: options.admin
|
|
293
|
+
}, comment, tag)
|
|
294
|
+
if(res.data.code === 200) {
|
|
295
|
+
log.success('组件库 - 已发布新版本!')
|
|
296
|
+
return
|
|
297
|
+
}
|
|
298
|
+
if (res.data.code === 100) {
|
|
299
|
+
log.error('组件库 - 无待发布版本')
|
|
300
|
+
return
|
|
301
|
+
}
|
|
302
|
+
if (res.data.code === 201) {
|
|
303
|
+
log.error('组件库 - comment 重复, 请使用有意义的comment')
|
|
304
|
+
return
|
|
305
|
+
} else {
|
|
306
|
+
if(res.data.msg) {
|
|
307
|
+
log.error(`组件库 - ${res.data.msg} RequestId: ${res.requestId}`)
|
|
308
|
+
} else {
|
|
309
|
+
log.error('组件库 - 未知错误')
|
|
310
|
+
}
|
|
311
|
+
return
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
227
316
|
async function _download(compsPath, compsName) {
|
|
228
317
|
await execWithLoading(
|
|
229
318
|
async () => {
|
package/src/constant.ts
CHANGED
|
@@ -68,6 +68,12 @@ export const ALL_COMMANDS = [
|
|
|
68
68
|
'fn trigger create',
|
|
69
69
|
'fn trigger delete',
|
|
70
70
|
'fn invoke',
|
|
71
|
+
'fn publish-version',
|
|
72
|
+
'fn list-function-versions',
|
|
73
|
+
'fn put-provisioned-concurrency',
|
|
74
|
+
'fn get-provisioned-concurrency',
|
|
75
|
+
'fn delete-provisioned-concurrency',
|
|
76
|
+
'fn config-route',
|
|
71
77
|
'functions run',
|
|
72
78
|
'storage upload',
|
|
73
79
|
'storage download',
|
|
@@ -94,3 +100,21 @@ export const ALL_COMMANDS = [
|
|
|
94
100
|
'run standalonegateway turn on',
|
|
95
101
|
'run standalonegateway turn off',
|
|
96
102
|
]
|
|
103
|
+
|
|
104
|
+
export const StatusMap = {
|
|
105
|
+
Active: '部署完成',
|
|
106
|
+
Creating: '创建中',
|
|
107
|
+
CreateFailed: '创建失败',
|
|
108
|
+
Updating: '更新中',
|
|
109
|
+
UpdateFailed: '更新失败',
|
|
110
|
+
Publishing: '函数版本发布中',
|
|
111
|
+
PublishFailed: '函数版本发布失败',
|
|
112
|
+
Deleting: '函数删除中',
|
|
113
|
+
DeleteFailed: '函数删除失败'
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export const ConcurrencyTaskStatus = {
|
|
117
|
+
Done: '已完成',
|
|
118
|
+
InProgress: '进行中',
|
|
119
|
+
Failed: '失败'
|
|
120
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { CloudBaseError } from '../error'
|
|
2
|
+
import { IUpdateFunctionAliasConfig, IGetFunctionAlias, IGetFunctionAliasRes } from '../types'
|
|
3
|
+
import { getFunctionService } from './base'
|
|
4
|
+
|
|
5
|
+
// 设置函数流量配置信息(ALIAS 配置)
|
|
6
|
+
export async function setFunctionAliasConfig(options: IUpdateFunctionAliasConfig) {
|
|
7
|
+
const { envId, functionName, name, functionVersion, description, routingConfig } = options
|
|
8
|
+
|
|
9
|
+
const scfService = await getFunctionService(envId)
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
await scfService.updateFunctionAliasConfig({
|
|
13
|
+
functionName,
|
|
14
|
+
name,
|
|
15
|
+
functionVersion,
|
|
16
|
+
description,
|
|
17
|
+
routingConfig
|
|
18
|
+
})
|
|
19
|
+
} catch (e) {
|
|
20
|
+
throw new CloudBaseError(`[${functionName}] 设置函数流量配置失败: ${e.message}`, {
|
|
21
|
+
code: e.code
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// 查询函数别名配置信息
|
|
27
|
+
export async function getFunctionAliasConfig(options: IGetFunctionAlias): Promise<IGetFunctionAliasRes> {
|
|
28
|
+
const { envId, functionName, name } = options
|
|
29
|
+
|
|
30
|
+
const scfService = await getFunctionService(envId)
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
return scfService.getFunctionAlias({
|
|
34
|
+
functionName,
|
|
35
|
+
name
|
|
36
|
+
})
|
|
37
|
+
} catch (e) {
|
|
38
|
+
throw new CloudBaseError(`[${functionName}] 查询函数别名配置失败: ${e.message}`, {
|
|
39
|
+
code: e.code
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { CloudBaseError } from '../error'
|
|
2
|
+
import { ISetProvisionedConcurrencyConfig, IGetProvisionedConcurrencyConfig, IGetProvisionedConcurrencyRes, IFunctionVersionsRes } from '../types'
|
|
3
|
+
import { getFunctionService } from './base'
|
|
4
|
+
|
|
5
|
+
// 设置函数预置并发
|
|
6
|
+
export async function setProvisionedConcurrencyConfig(options: ISetProvisionedConcurrencyConfig) {
|
|
7
|
+
const { envId, functionName, qualifier, versionProvisionedConcurrencyNum } = options
|
|
8
|
+
|
|
9
|
+
const scfService = await getFunctionService(envId)
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
await scfService.setProvisionedConcurrencyConfig({
|
|
13
|
+
functionName,
|
|
14
|
+
qualifier,
|
|
15
|
+
versionProvisionedConcurrencyNum
|
|
16
|
+
})
|
|
17
|
+
} catch (e) {
|
|
18
|
+
throw new CloudBaseError(`[${functionName}] 设置函数预置并发失败: ${e.message}`, {
|
|
19
|
+
code: e.code
|
|
20
|
+
})
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// 查看函数预置并发
|
|
25
|
+
export async function getProvisionedConcurrencyConfig(options: IGetProvisionedConcurrencyConfig): Promise<IGetProvisionedConcurrencyRes> {
|
|
26
|
+
const { envId, functionName, qualifier } = options
|
|
27
|
+
const scfService = await getFunctionService(envId)
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
return scfService.getProvisionedConcurrencyConfig({
|
|
31
|
+
functionName,
|
|
32
|
+
qualifier,
|
|
33
|
+
})
|
|
34
|
+
} catch (e) {
|
|
35
|
+
throw new CloudBaseError(`[${functionName}] 查看函数预置并发信息失败: ${e.message}`, {
|
|
36
|
+
code: e.code
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// 删除函数预置并发
|
|
42
|
+
export async function deleteProvisionedConcurrencyConfig(options: IGetProvisionedConcurrencyConfig): Promise<void> {
|
|
43
|
+
const { envId, functionName, qualifier } = options
|
|
44
|
+
const scfService = await getFunctionService(envId)
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
await scfService.deleteProvisionedConcurrencyConfig({
|
|
48
|
+
functionName,
|
|
49
|
+
qualifier
|
|
50
|
+
})
|
|
51
|
+
} catch (e) {
|
|
52
|
+
throw new CloudBaseError(`[${functionName}] 删除函数预置并发失败: ${e.message}`, {
|
|
53
|
+
code: e.code
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
package/src/function/index.ts
CHANGED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { CloudBaseError } from '../error'
|
|
2
|
+
import { IPublishVersionParams, IListFunctionVersionParams, IFunctionVersionsRes } from '../types'
|
|
3
|
+
import { getFunctionService } from './base'
|
|
4
|
+
|
|
5
|
+
// 发布云函数新版本
|
|
6
|
+
export async function publishVersion(options: IPublishVersionParams) {
|
|
7
|
+
const { envId, functionName, description = '' } = options
|
|
8
|
+
|
|
9
|
+
const scfService = await getFunctionService(envId)
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
await scfService.publishVersion({
|
|
13
|
+
functionName,
|
|
14
|
+
description
|
|
15
|
+
})
|
|
16
|
+
} catch (e) {
|
|
17
|
+
throw new CloudBaseError(`[${functionName}] 函数发布新版本失败: ${e.message}`, {
|
|
18
|
+
code: e.code
|
|
19
|
+
})
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// 查看函数所有版本
|
|
24
|
+
export async function listFunctionVersions(options: IListFunctionVersionParams): Promise<IFunctionVersionsRes> {
|
|
25
|
+
const { envId, functionName, offset = 0, limit = 20 } = options
|
|
26
|
+
const scfService = await getFunctionService(envId)
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
return scfService.listVersionByFunction({
|
|
30
|
+
functionName,
|
|
31
|
+
offset,
|
|
32
|
+
limit
|
|
33
|
+
})
|
|
34
|
+
} catch (e) {
|
|
35
|
+
throw new CloudBaseError(`[${functionName}] 查看寒函数版本列表失败: ${e.message}`, {
|
|
36
|
+
code: e.code
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -435,4 +435,99 @@ export interface ITurnOffStandaloneGateway {
|
|
|
435
435
|
export interface IDestroyStandaloneGateway {
|
|
436
436
|
envId: string,
|
|
437
437
|
gatewayName: string
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
export interface IPublishVersionParams {
|
|
441
|
+
envId: string
|
|
442
|
+
functionName: string
|
|
443
|
+
description?: string
|
|
444
|
+
}
|
|
445
|
+
export interface IListFunctionVersionParams {
|
|
446
|
+
envId: string
|
|
447
|
+
functionName: string
|
|
448
|
+
offset?: number
|
|
449
|
+
limit?: number
|
|
450
|
+
order?: string
|
|
451
|
+
orderBy?: string
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
export interface IFunctionVersion {
|
|
455
|
+
Version: string
|
|
456
|
+
Description: string
|
|
457
|
+
AddTime: string
|
|
458
|
+
ModTime: string
|
|
459
|
+
Status: string //
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
export interface IFunctionVersionsRes {
|
|
463
|
+
FunctionVersion: string[]
|
|
464
|
+
Versions: IFunctionVersion[]
|
|
465
|
+
TotalCount: number
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
export interface ISetProvisionedConcurrencyConfig {
|
|
469
|
+
envId: string
|
|
470
|
+
functionName: string
|
|
471
|
+
qualifier: string
|
|
472
|
+
versionProvisionedConcurrencyNum: number
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
export interface IGetProvisionedConcurrencyConfig {
|
|
476
|
+
functionName: string
|
|
477
|
+
qualifier?: string
|
|
478
|
+
envId: string
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
export interface IGetProvisionedConcurrencyRes {
|
|
482
|
+
UnallocatedConcurrencyNum: number
|
|
483
|
+
Allocated: IVersionProvisionedConcurrencyInfo[]
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
export interface IVersionProvisionedConcurrencyInfo {
|
|
487
|
+
AllocatedProvisionedConcurrencyNum: number // 设置的预置并发数。
|
|
488
|
+
AvailableProvisionedConcurrencyNum: number // 当前已完成预置的并发数。
|
|
489
|
+
Status: string // 预置任务状态,Done表示已完成,InProgress表示进行中,Failed表示部分或全部失败。
|
|
490
|
+
StatusReason: string // 对预置任务状态Status的说明。
|
|
491
|
+
Qualifier: string // 版本号
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
export interface IUpdateFunctionAliasConfig {
|
|
495
|
+
envId: string
|
|
496
|
+
functionName: string // 函数名
|
|
497
|
+
name: string // 函数别名 如$DEFAULT
|
|
498
|
+
functionVersion: string // 函数版本
|
|
499
|
+
description?: string // 别名描述
|
|
500
|
+
routingConfig?: IRoutingConfig
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
export interface IRoutingConfig {
|
|
504
|
+
AdditionalVersionWeights?: IVersionWeight[]
|
|
505
|
+
AddtionVersionMatchs?: IVersionMatch[]
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
export interface IVersionMatch {
|
|
509
|
+
Version: string // 函数版本名称
|
|
510
|
+
Key: string // 匹配规则的key,调用时通过传key来匹配规则路由到指定版本 header方式:key填写"invoke.headers.User",并在 invoke 调用函数时传参 RoutingKey:{"User":"value"}规则匹配调用
|
|
511
|
+
Method: string // 匹配方式。取值范围:range:范围匹配 exact:字符串精确匹配
|
|
512
|
+
Expression: string //
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
export interface IVersionWeight {
|
|
516
|
+
Version: string
|
|
517
|
+
Weight: number
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
export interface IGetFunctionAlias {
|
|
521
|
+
envId: string
|
|
522
|
+
functionName: string // 函数名称
|
|
523
|
+
name: string // 别名
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
export interface IGetFunctionAliasRes {
|
|
527
|
+
FunctionVersion: string
|
|
528
|
+
Name: string
|
|
529
|
+
RoutingConfig: IRoutingConfig
|
|
530
|
+
Description: string
|
|
531
|
+
AddTime: string
|
|
532
|
+
ModTime: string
|
|
438
533
|
}
|