@cloudbase/cli 2.0.3 → 2.0.5

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.
Files changed (217) hide show
  1. package/.editorconfig +9 -9
  2. package/.eslintignore +7 -7
  3. package/.eslintrc +35 -35
  4. package/.prettierrc.js +29 -29
  5. package/.vscode/launch.json +16 -16
  6. package/LICENSE +5 -5
  7. package/README.md +35 -35
  8. package/bin/cloudbase.js +5 -5
  9. package/changelog.md +6 -6
  10. package/jest.config.js +17 -17
  11. package/lib/commands/account/login.js +18 -18
  12. package/lib/commands/run/list.js +2 -3
  13. package/lib/commands/storage/storage.js +1 -1
  14. package/lib/env/login.js +7 -7
  15. package/lib/utils/tcbrApi/callTcbrApi.js +2 -2
  16. package/package.json +3 -3
  17. package/post-install.js +61 -61
  18. package/runtime/nodejs/bootstrap.js +255 -255
  19. package/runtime/nodejs/runtime.js +183 -183
  20. package/src/auth/index.ts +1 -1
  21. package/src/auth/login.ts +91 -91
  22. package/src/auth/logout.ts +7 -7
  23. package/src/commands/account/index.ts +2 -2
  24. package/src/commands/account/login.ts +192 -192
  25. package/src/commands/account/logout.ts +24 -24
  26. package/src/commands/env/base.ts +90 -90
  27. package/src/commands/env/create.ts +92 -92
  28. package/src/commands/env/domain.ts +186 -186
  29. package/src/commands/env/index.ts +4 -4
  30. package/src/commands/env/login.ts +235 -235
  31. package/src/commands/framework/index.ts +124 -124
  32. package/src/commands/functions/alias/getRoute.ts +76 -76
  33. package/src/commands/functions/alias/index.ts +2 -2
  34. package/src/commands/functions/alias/setRoute.ts +82 -82
  35. package/src/commands/functions/code-download.ts +100 -100
  36. package/src/commands/functions/code-update.ts +62 -62
  37. package/src/commands/functions/concurrency/delete.ts +45 -45
  38. package/src/commands/functions/concurrency/index.ts +2 -2
  39. package/src/commands/functions/concurrency/list.ts +58 -58
  40. package/src/commands/functions/concurrency/set.ts +47 -47
  41. package/src/commands/functions/config-update.ts +76 -76
  42. package/src/commands/functions/copy.ts +62 -62
  43. package/src/commands/functions/delete.ts +79 -79
  44. package/src/commands/functions/deploy.ts +293 -293
  45. package/src/commands/functions/detail.ts +138 -138
  46. package/src/commands/functions/index.ts +16 -16
  47. package/src/commands/functions/invoke.ts +121 -121
  48. package/src/commands/functions/layer/bind.ts +182 -182
  49. package/src/commands/functions/layer/common.ts +8 -8
  50. package/src/commands/functions/layer/create.ts +49 -49
  51. package/src/commands/functions/layer/delete.ts +73 -73
  52. package/src/commands/functions/layer/download.ts +92 -92
  53. package/src/commands/functions/layer/index.ts +7 -7
  54. package/src/commands/functions/layer/list.ts +94 -94
  55. package/src/commands/functions/layer/sort.ts +76 -76
  56. package/src/commands/functions/list.ts +68 -68
  57. package/src/commands/functions/log.ts +148 -148
  58. package/src/commands/functions/run.ts +249 -249
  59. package/src/commands/functions/trigger-create.ts +79 -79
  60. package/src/commands/functions/trigger-delete.ts +105 -105
  61. package/src/commands/functions/version/index.ts +1 -1
  62. package/src/commands/functions/version/list.ts +73 -73
  63. package/src/commands/functions/version/publish.ts +43 -43
  64. package/src/commands/gateway/create.ts +109 -109
  65. package/src/commands/gateway/delete.ts +81 -81
  66. package/src/commands/gateway/domain.ts +159 -159
  67. package/src/commands/gateway/index.ts +5 -5
  68. package/src/commands/gateway/list.ts +76 -76
  69. package/src/commands/gateway/switch.ts +107 -107
  70. package/src/commands/helpers/index.ts +2 -2
  71. package/src/commands/helpers/init.ts +431 -431
  72. package/src/commands/helpers/new.ts +117 -117
  73. package/src/commands/helpers/open.ts +67 -67
  74. package/src/commands/hosting/hosting.ts +360 -360
  75. package/src/commands/index.ts +13 -13
  76. package/src/commands/lowcode/app.ts +34 -34
  77. package/src/commands/lowcode/comps.ts +322 -322
  78. package/src/commands/lowcode/index.ts +1 -1
  79. package/src/commands/lowcode/utils.ts +24 -24
  80. package/src/commands/run/image/index.ts +4 -4
  81. package/src/commands/run/list.ts +2 -3
  82. package/src/commands/run/standalonegateway/common.ts +7 -7
  83. package/src/commands/run/standalonegateway/create.ts +85 -85
  84. package/src/commands/run/standalonegateway/destroy.ts +59 -59
  85. package/src/commands/run/standalonegateway/index.ts +4 -4
  86. package/src/commands/run/standalonegateway/list.ts +53 -53
  87. package/src/commands/run/standalonegateway/package.ts +62 -62
  88. package/src/commands/run/standalonegateway/turn.ts +63 -63
  89. package/src/commands/run/version/index.ts +4 -4
  90. package/src/commands/smart.ts +132 -132
  91. package/src/commands/storage/storage.ts +464 -464
  92. package/src/commands/third/thirdAttach.ts +49 -49
  93. package/src/completion/index.ts +13 -13
  94. package/src/decorators/captureError.ts +25 -25
  95. package/src/decorators/constants.ts +12 -12
  96. package/src/decorators/deprecate.ts +25 -25
  97. package/src/decorators/guard.ts +42 -42
  98. package/src/decorators/index.ts +7 -7
  99. package/src/decorators/injectParams.ts +54 -54
  100. package/src/decorators/params/common.ts +28 -28
  101. package/src/decorators/params/index.ts +35 -35
  102. package/src/env/domain.ts +33 -33
  103. package/src/env/index.ts +63 -63
  104. package/src/env/login.ts +80 -80
  105. package/src/error.ts +36 -36
  106. package/src/function/alias.ts +43 -43
  107. package/src/function/base.ts +253 -253
  108. package/src/function/code.ts +55 -55
  109. package/src/function/concurrency.ts +57 -57
  110. package/src/function/create.ts +78 -78
  111. package/src/function/delete.ts +42 -42
  112. package/src/function/index.ts +10 -10
  113. package/src/function/layer/attach.ts +68 -68
  114. package/src/function/layer/create.ts +63 -63
  115. package/src/function/layer/delete.ts +21 -21
  116. package/src/function/layer/download.ts +54 -54
  117. package/src/function/layer/index.ts +7 -7
  118. package/src/function/layer/list.ts +32 -32
  119. package/src/function/layer/sort.ts +24 -24
  120. package/src/function/trigger.ts +97 -97
  121. package/src/function/update.ts +35 -35
  122. package/src/function/version.ts +38 -38
  123. package/src/function/vpc.ts +22 -22
  124. package/src/gateway/index.ts +137 -137
  125. package/src/hosting.ts +212 -212
  126. package/src/index.ts +13 -13
  127. package/src/logger.ts +17 -17
  128. package/src/run/create.ts +23 -23
  129. package/src/run/delete.ts +15 -15
  130. package/src/run/image/build.ts +36 -36
  131. package/src/run/image/delete.ts +13 -13
  132. package/src/run/image/index.ts +3 -3
  133. package/src/run/image/info.ts +26 -26
  134. package/src/run/list.ts +29 -29
  135. package/src/run/repo.ts +24 -24
  136. package/src/run/standalonegateway/create.ts +24 -24
  137. package/src/run/standalonegateway/destroy.ts +19 -19
  138. package/src/run/standalonegateway/index.ts +4 -4
  139. package/src/run/standalonegateway/list.ts +74 -74
  140. package/src/run/standalonegateway/package/list.ts +24 -24
  141. package/src/run/standalonegateway/turn/index.ts +1 -1
  142. package/src/run/standalonegateway/turn/off.ts +19 -19
  143. package/src/run/standalonegateway/turn/on.ts +19 -19
  144. package/src/run/version/create.ts +68 -68
  145. package/src/run/version/delete.ts +15 -15
  146. package/src/run/version/index.ts +5 -5
  147. package/src/run/version/list.ts +16 -16
  148. package/src/run/version/modify.ts +16 -16
  149. package/src/run/version/repo.ts +27 -27
  150. package/src/run/version/update.ts +58 -58
  151. package/src/storage.ts +114 -114
  152. package/src/third/index.ts +12 -12
  153. package/src/utils/auth.ts +15 -15
  154. package/src/utils/cli-table.ts +23 -23
  155. package/src/utils/config.ts +39 -39
  156. package/src/utils/env.ts +244 -244
  157. package/src/utils/fs/del.ts +5 -5
  158. package/src/utils/fs/index.ts +71 -71
  159. package/src/utils/function-packer.ts +97 -97
  160. package/src/utils/log.ts +81 -81
  161. package/src/utils/net/cloud-api-request.ts +62 -62
  162. package/src/utils/net/credential.ts +53 -53
  163. package/src/utils/net/index.ts +4 -4
  164. package/src/utils/net/manager-service.ts +36 -36
  165. package/src/utils/net/proxy.ts +6 -6
  166. package/src/utils/notice.ts +28 -28
  167. package/src/utils/output/highlight.ts +5 -5
  168. package/src/utils/output/index.ts +2 -2
  169. package/src/utils/output/link.ts +10 -10
  170. package/src/utils/output/loading.ts +82 -82
  171. package/src/utils/parallel.ts +82 -82
  172. package/src/utils/platform/index.ts +2 -2
  173. package/src/utils/platform/mac.ts +21 -21
  174. package/src/utils/platform/os.ts +64 -64
  175. package/src/utils/platform/port.ts +10 -10
  176. package/src/utils/progress-bar.ts +38 -38
  177. package/src/utils/prompt/select.ts +59 -59
  178. package/src/utils/reporter/agree.ts +20 -20
  179. package/src/utils/reporter/download.ts +26 -26
  180. package/src/utils/reporter/index.ts +3 -3
  181. package/src/utils/reporter/usage.ts +20 -20
  182. package/src/utils/store/auth.ts +49 -49
  183. package/src/utils/store/common.ts +8 -8
  184. package/src/utils/store/db.ts +68 -68
  185. package/src/utils/store/index.ts +4 -4
  186. package/src/utils/store/usage.ts +12 -12
  187. package/src/utils/tcbrApi/callTcbrApi.ts +1 -1
  188. package/src/utils/template.ts +170 -170
  189. package/src/utils/tools/encoding.ts +8 -8
  190. package/src/utils/tools/index.ts +4 -4
  191. package/src/utils/tools/object.ts +33 -33
  192. package/src/utils/tools/time.ts +38 -38
  193. package/src/utils/tools/uid.ts +19 -19
  194. package/templates/html/loginFail.html +90 -90
  195. package/templates/html/loginSuccess.html +86 -86
  196. package/templates/server/node/_gitignore +54 -54
  197. package/templates/server/node/cloudbaserc.json +10 -10
  198. package/templates/server/node/index.js +5 -5
  199. package/templates/server/node/package.json +9 -9
  200. package/tsconfig.json +19 -19
  201. package/tsconfig.test.json +13 -13
  202. package/.vscode/settings.json +0 -3
  203. package/lib/utils/tcbrApi/tcbr-cloud-api/cloud-api-service.js +0 -268
  204. package/lib/utils/tcbrApi/tcbr-cloud-api/error.js +0 -17
  205. package/lib/utils/tcbrApi/tcbr-cloud-api/index.js +0 -17
  206. package/lib/utils/tcbrApi/tcbr-cloud-api/request.js +0 -40
  207. package/lib/utils/tcbrApi/tcbr-cloud-api-request.js +0 -61
  208. package/src/utils/tcbrApi/tcbr-cloud-api/cloud-api-service.ts +0 -363
  209. package/src/utils/tcbrApi/tcbr-cloud-api/error.ts +0 -30
  210. package/src/utils/tcbrApi/tcbr-cloud-api/index.ts +0 -1
  211. package/src/utils/tcbrApi/tcbr-cloud-api/request.ts +0 -28
  212. package/src/utils/tcbrApi/tcbr-cloud-api-request.ts +0 -66
  213. package/types/utils/tcbrApi/tcbr-cloud-api/cloud-api-service.d.ts +0 -51
  214. package/types/utils/tcbrApi/tcbr-cloud-api/error.d.ts +0 -20
  215. package/types/utils/tcbrApi/tcbr-cloud-api/index.d.ts +0 -1
  216. package/types/utils/tcbrApi/tcbr-cloud-api/request.d.ts +0 -4
  217. package/types/utils/tcbrApi/tcbr-cloud-api-request.d.ts +0 -9
@@ -1,293 +1,293 @@
1
- import path from 'path'
2
- import inquirer from 'inquirer'
3
- import { getRegion } from '@cloudbase/toolbox'
4
- import { Command, ICommand } from '../common'
5
- import { CloudBaseError } from '../../error'
6
- import { createFunction } from '../../function'
7
- import { queryGateway, createGateway } from '../../gateway'
8
- import {
9
- logger,
10
- random,
11
- isDirectory,
12
- loadingFactory,
13
- genClickableLink,
14
- highlightCommand,
15
- checkFullAccess,
16
- AsyncTaskParallelController
17
- } from '../../utils'
18
- import { ICreateFunctionOptions } from '../../types'
19
- import { DefaultFunctionDeployConfig } from '../../constant'
20
- import { InjectParams, CmdContext, ArgsParams, Log, Logger } from '../../decorators'
21
-
22
- const regionIdMap = {
23
- 'ap-guangzhou': 1,
24
- 'ap-shanghai': 4,
25
- 'ap-beijing': 8
26
- }
27
-
28
- @ICommand()
29
- export class FunctionDeploy extends Command {
30
- get options() {
31
- return {
32
- cmd: 'fn',
33
- childCmd: 'deploy [name]',
34
- deprecateCmd: 'functions:deploy [name]',
35
- options: [
36
- {
37
- flags: '-e, --envId <envId>',
38
- desc: '环境 Id'
39
- },
40
- {
41
- flags: '--code-secret <codeSecret>',
42
- desc: '传入此参数将保护代码,格式为 36 位大小写字母和数字'
43
- },
44
- {
45
- flags: '--force',
46
- desc: '如果存在同名函数,上传后覆盖同名函数'
47
- },
48
- {
49
- flags: '--path <path>',
50
- desc: '自动创建HTTP 访问服务访问路径'
51
- },
52
- {
53
- flags: '--all',
54
- desc: '部署配置文件中的包含的全部云函数'
55
- },
56
- {
57
- flags: '--dir <dir>',
58
- desc: '指定云函数的文件夹路径'
59
- }
60
- ],
61
- desc: '部署云函数'
62
- }
63
- }
64
-
65
- @InjectParams()
66
- async execute(@CmdContext() ctx, @ArgsParams() params, @Log() log: Logger) {
67
- const { envId, config, options } = ctx
68
- const { functions } = config
69
- const { force, codeSecret, path: access, all, dir } = options
70
- const functionRootPath = path.join(process.cwd(), config.functionRoot)
71
- const name = params?.[0]
72
-
73
- if (access && checkFullAccess(access)) {
74
- log.warn('--path 参数已更换为HTTP 访问服务路径,请使用 --dir 指定部署函数的文件夹路径')
75
- }
76
-
77
- if (access && access[0] !== '/') {
78
- throw new CloudBaseError('HTTP 访问服务路径必须以 / 开头')
79
- }
80
-
81
- // 当没有指定函数名称或函数路径时,询问处理否部署全部云函数
82
- if ((!name && !dir) || all) {
83
- return this.deployAllFunction({
84
- all,
85
- envId,
86
- force,
87
- access,
88
- functions,
89
- codeSecret,
90
- functionRootPath
91
- })
92
- }
93
-
94
- // 校验函数路径是否存在
95
- if (dir) {
96
- checkFullAccess(dir, true)
97
- if (!isDirectory(dir)) {
98
- throw new CloudBaseError('--dir 参数必须指定为云函数的文件夹路径')
99
- }
100
- }
101
-
102
- let newFunction
103
- if (functions && functions.length > 0) {
104
- newFunction = functions.find((item) => item.name === name)
105
- }
106
-
107
- // 没有配置,使用默认配置
108
- if (!newFunction || !newFunction.name) {
109
- log.info('未找到函数发布配置,使用默认配置 => 运行时:Nodejs10.15/在线安装依赖')
110
- newFunction = {
111
- name,
112
- ...DefaultFunctionDeployConfig
113
- }
114
- }
115
-
116
- const loading = loadingFactory()
117
-
118
- loading.start('云函数部署中...')
119
-
120
- try {
121
- await createFunction({
122
- force,
123
- envId,
124
- codeSecret,
125
- functionRootPath,
126
- func: newFunction,
127
- accessPath: access,
128
- functionPath: dir
129
- })
130
- loading.succeed(`[${newFunction.name}] 云函数部署成功!`)
131
- // await genApiGateway(envId, name)
132
- this.printSuccessTips(envId)
133
- } catch (e) {
134
- // 询问是否覆盖同名函数
135
- loading.stop()
136
- await this.handleDeployFail(e, {
137
- envId,
138
- codeSecret,
139
- functionRootPath,
140
- func: newFunction,
141
- accessPath: access,
142
- functionPath: dir
143
- })
144
- }
145
-
146
- if (access || newFunction.path) {
147
- const link = genClickableLink(
148
- `https://${envId}.service.tcloudbase.com${access || newFunction.path}`
149
- )
150
- console.log(`\n云函数HTTP 访问服务访问链接:${link}`)
151
- }
152
- }
153
-
154
- async deployAllFunction(options: any) {
155
- const { functions = [], envId, force, codeSecret, functionRootPath, all, access } = options
156
-
157
- // 指定 all 参数,直接部署全部云函数
158
- if (!all) {
159
- const { isBatch } = await inquirer.prompt({
160
- type: 'confirm',
161
- name: 'isBatch',
162
- message: '没有指定需要部署的云函数,是否部署配置文件中的全部云函数?',
163
- default: false
164
- })
165
-
166
- // 用户不部署全部函数,报错
167
- if (!isBatch) {
168
- throw new CloudBaseError(
169
- '请指定需要部署的云函数的名称或通过 --path 参数指定需要部署的函数的路径!'
170
- )
171
- }
172
- }
173
-
174
- // 批量部署云函数
175
- const loading = loadingFactory()
176
- const tasks = functions.map((func) => async () => {
177
- loading.start('云函数部署中')
178
- try {
179
- await createFunction({
180
- func,
181
- envId,
182
- force,
183
- codeSecret,
184
- functionRootPath,
185
- accessPath: access
186
- })
187
- loading.succeed(`[${func.name}] 云函数部署成功`)
188
- } catch (e) {
189
- loading.stop()
190
- await this.handleDeployFail(e, {
191
- func,
192
- envId,
193
- codeSecret,
194
- functionRootPath,
195
- accessPath: access
196
- })
197
- }
198
- })
199
-
200
- if (tasks.length > 5) {
201
- logger.info('函数数量较多,将使用队列部署')
202
- }
203
-
204
- // 控制函数创建并发
205
- const asyncTaskController = new AsyncTaskParallelController(5, 50)
206
- asyncTaskController.loadTasks(tasks)
207
- const results = await asyncTaskController.run()
208
-
209
- // 输出信息
210
- const success = results.filter((_) => !_)
211
- logger.success(`成功部署 ${success?.length} 个函数`)
212
- // 部署失败
213
- const err = results.filter((_) => _)
214
- err?.length && logger.error(`${err?.length} 个云函数部署失败`)
215
- }
216
-
217
- async handleDeployFail(e: CloudBaseError, options: ICreateFunctionOptions) {
218
- const { envId, codeSecret, functionRootPath, func, functionPath, accessPath } = options
219
- const loading = loadingFactory()
220
-
221
- if (e.code === 'ResourceInUse.FunctionName' || e.code === 'ResourceInUse.Function') {
222
- const { force } = await inquirer.prompt({
223
- type: 'confirm',
224
- name: 'force',
225
- message: `存在同名云函数:[${func.name}],是否覆盖原函数代码与配置`,
226
- default: false
227
- })
228
-
229
- if (force) {
230
- loading.start('云函数部署中...')
231
- try {
232
- await createFunction({
233
- func,
234
- envId,
235
- codeSecret,
236
- accessPath,
237
- force: true,
238
- functionPath,
239
- functionRootPath
240
- })
241
- loading.succeed(`[${func.name}] 云函数部署成功!`)
242
- // await genApiGateway(envId, name)
243
- await this.printSuccessTips(envId)
244
- } catch (e) {
245
- loading.stop()
246
- throw e
247
- }
248
- return
249
- }
250
- }
251
-
252
- throw e
253
- }
254
-
255
- @InjectParams()
256
- async printSuccessTips(envId: string, @Log() log?: Logger) {
257
- let url = `https://console.cloud.tencent.com/tcb/scf?envId=${envId}`
258
- const region = await getRegion()
259
- url += `&rid=${regionIdMap[region]}`
260
- const link = genClickableLink(url)
261
- log.breakLine()
262
- log.info(`控制台查看函数详情或创建HTTP 访问服务链接 🔗:${link}`)
263
- log.info(`使用 ${highlightCommand('cloudbase functions:list')} 命令查看已部署云函数`)
264
- }
265
-
266
- // 创建函数 API 网关
267
- async genApiGateway(envId: string, name: string) {
268
- const loading = loadingFactory()
269
- // 检查是否绑定了 HTTP 网关
270
- const res = await queryGateway({
271
- name,
272
- envId
273
- })
274
- // 未开启,不生成 HTTP 调用了链接
275
- if (res?.EnableService === false) return
276
- loading.start('生成云函数HTTP 访问服务中...')
277
-
278
- let path
279
- if (res?.APISet?.length > 0) {
280
- path = res.APISet[0]?.Path
281
- } else {
282
- path = `/${random(12)}`
283
- await createGateway({
284
- envId,
285
- name,
286
- path
287
- })
288
- }
289
- loading.stop()
290
- const link = genClickableLink(`https://${envId}.service.tcloudbase.com${path}`)
291
- console.log(`\n云函数HTTP 访问服务链接:${link}`)
292
- }
293
- }
1
+ import path from 'path'
2
+ import inquirer from 'inquirer'
3
+ import { getRegion } from '@cloudbase/toolbox'
4
+ import { Command, ICommand } from '../common'
5
+ import { CloudBaseError } from '../../error'
6
+ import { createFunction } from '../../function'
7
+ import { queryGateway, createGateway } from '../../gateway'
8
+ import {
9
+ logger,
10
+ random,
11
+ isDirectory,
12
+ loadingFactory,
13
+ genClickableLink,
14
+ highlightCommand,
15
+ checkFullAccess,
16
+ AsyncTaskParallelController
17
+ } from '../../utils'
18
+ import { ICreateFunctionOptions } from '../../types'
19
+ import { DefaultFunctionDeployConfig } from '../../constant'
20
+ import { InjectParams, CmdContext, ArgsParams, Log, Logger } from '../../decorators'
21
+
22
+ const regionIdMap = {
23
+ 'ap-guangzhou': 1,
24
+ 'ap-shanghai': 4,
25
+ 'ap-beijing': 8
26
+ }
27
+
28
+ @ICommand()
29
+ export class FunctionDeploy extends Command {
30
+ get options() {
31
+ return {
32
+ cmd: 'fn',
33
+ childCmd: 'deploy [name]',
34
+ deprecateCmd: 'functions:deploy [name]',
35
+ options: [
36
+ {
37
+ flags: '-e, --envId <envId>',
38
+ desc: '环境 Id'
39
+ },
40
+ {
41
+ flags: '--code-secret <codeSecret>',
42
+ desc: '传入此参数将保护代码,格式为 36 位大小写字母和数字'
43
+ },
44
+ {
45
+ flags: '--force',
46
+ desc: '如果存在同名函数,上传后覆盖同名函数'
47
+ },
48
+ {
49
+ flags: '--path <path>',
50
+ desc: '自动创建HTTP 访问服务访问路径'
51
+ },
52
+ {
53
+ flags: '--all',
54
+ desc: '部署配置文件中的包含的全部云函数'
55
+ },
56
+ {
57
+ flags: '--dir <dir>',
58
+ desc: '指定云函数的文件夹路径'
59
+ }
60
+ ],
61
+ desc: '部署云函数'
62
+ }
63
+ }
64
+
65
+ @InjectParams()
66
+ async execute(@CmdContext() ctx, @ArgsParams() params, @Log() log: Logger) {
67
+ const { envId, config, options } = ctx
68
+ const { functions } = config
69
+ const { force, codeSecret, path: access, all, dir } = options
70
+ const functionRootPath = path.join(process.cwd(), config.functionRoot)
71
+ const name = params?.[0]
72
+
73
+ if (access && checkFullAccess(access)) {
74
+ log.warn('--path 参数已更换为HTTP 访问服务路径,请使用 --dir 指定部署函数的文件夹路径')
75
+ }
76
+
77
+ if (access && access[0] !== '/') {
78
+ throw new CloudBaseError('HTTP 访问服务路径必须以 / 开头')
79
+ }
80
+
81
+ // 当没有指定函数名称或函数路径时,询问处理否部署全部云函数
82
+ if ((!name && !dir) || all) {
83
+ return this.deployAllFunction({
84
+ all,
85
+ envId,
86
+ force,
87
+ access,
88
+ functions,
89
+ codeSecret,
90
+ functionRootPath
91
+ })
92
+ }
93
+
94
+ // 校验函数路径是否存在
95
+ if (dir) {
96
+ checkFullAccess(dir, true)
97
+ if (!isDirectory(dir)) {
98
+ throw new CloudBaseError('--dir 参数必须指定为云函数的文件夹路径')
99
+ }
100
+ }
101
+
102
+ let newFunction
103
+ if (functions && functions.length > 0) {
104
+ newFunction = functions.find((item) => item.name === name)
105
+ }
106
+
107
+ // 没有配置,使用默认配置
108
+ if (!newFunction || !newFunction.name) {
109
+ log.info('未找到函数发布配置,使用默认配置 => 运行时:Nodejs10.15/在线安装依赖')
110
+ newFunction = {
111
+ name,
112
+ ...DefaultFunctionDeployConfig
113
+ }
114
+ }
115
+
116
+ const loading = loadingFactory()
117
+
118
+ loading.start('云函数部署中...')
119
+
120
+ try {
121
+ await createFunction({
122
+ force,
123
+ envId,
124
+ codeSecret,
125
+ functionRootPath,
126
+ func: newFunction,
127
+ accessPath: access,
128
+ functionPath: dir
129
+ })
130
+ loading.succeed(`[${newFunction.name}] 云函数部署成功!`)
131
+ // await genApiGateway(envId, name)
132
+ this.printSuccessTips(envId)
133
+ } catch (e) {
134
+ // 询问是否覆盖同名函数
135
+ loading.stop()
136
+ await this.handleDeployFail(e, {
137
+ envId,
138
+ codeSecret,
139
+ functionRootPath,
140
+ func: newFunction,
141
+ accessPath: access,
142
+ functionPath: dir
143
+ })
144
+ }
145
+
146
+ if (access || newFunction.path) {
147
+ const link = genClickableLink(
148
+ `https://${envId}.service.tcloudbase.com${access || newFunction.path}`
149
+ )
150
+ console.log(`\n云函数HTTP 访问服务访问链接:${link}`)
151
+ }
152
+ }
153
+
154
+ async deployAllFunction(options: any) {
155
+ const { functions = [], envId, force, codeSecret, functionRootPath, all, access } = options
156
+
157
+ // 指定 all 参数,直接部署全部云函数
158
+ if (!all) {
159
+ const { isBatch } = await inquirer.prompt({
160
+ type: 'confirm',
161
+ name: 'isBatch',
162
+ message: '没有指定需要部署的云函数,是否部署配置文件中的全部云函数?',
163
+ default: false
164
+ })
165
+
166
+ // 用户不部署全部函数,报错
167
+ if (!isBatch) {
168
+ throw new CloudBaseError(
169
+ '请指定需要部署的云函数的名称或通过 --path 参数指定需要部署的函数的路径!'
170
+ )
171
+ }
172
+ }
173
+
174
+ // 批量部署云函数
175
+ const loading = loadingFactory()
176
+ const tasks = functions.map((func) => async () => {
177
+ loading.start('云函数部署中')
178
+ try {
179
+ await createFunction({
180
+ func,
181
+ envId,
182
+ force,
183
+ codeSecret,
184
+ functionRootPath,
185
+ accessPath: access
186
+ })
187
+ loading.succeed(`[${func.name}] 云函数部署成功`)
188
+ } catch (e) {
189
+ loading.stop()
190
+ await this.handleDeployFail(e, {
191
+ func,
192
+ envId,
193
+ codeSecret,
194
+ functionRootPath,
195
+ accessPath: access
196
+ })
197
+ }
198
+ })
199
+
200
+ if (tasks.length > 5) {
201
+ logger.info('函数数量较多,将使用队列部署')
202
+ }
203
+
204
+ // 控制函数创建并发
205
+ const asyncTaskController = new AsyncTaskParallelController(5, 50)
206
+ asyncTaskController.loadTasks(tasks)
207
+ const results = await asyncTaskController.run()
208
+
209
+ // 输出信息
210
+ const success = results.filter((_) => !_)
211
+ logger.success(`成功部署 ${success?.length} 个函数`)
212
+ // 部署失败
213
+ const err = results.filter((_) => _)
214
+ err?.length && logger.error(`${err?.length} 个云函数部署失败`)
215
+ }
216
+
217
+ async handleDeployFail(e: CloudBaseError, options: ICreateFunctionOptions) {
218
+ const { envId, codeSecret, functionRootPath, func, functionPath, accessPath } = options
219
+ const loading = loadingFactory()
220
+
221
+ if (e.code === 'ResourceInUse.FunctionName' || e.code === 'ResourceInUse.Function') {
222
+ const { force } = await inquirer.prompt({
223
+ type: 'confirm',
224
+ name: 'force',
225
+ message: `存在同名云函数:[${func.name}],是否覆盖原函数代码与配置`,
226
+ default: false
227
+ })
228
+
229
+ if (force) {
230
+ loading.start('云函数部署中...')
231
+ try {
232
+ await createFunction({
233
+ func,
234
+ envId,
235
+ codeSecret,
236
+ accessPath,
237
+ force: true,
238
+ functionPath,
239
+ functionRootPath
240
+ })
241
+ loading.succeed(`[${func.name}] 云函数部署成功!`)
242
+ // await genApiGateway(envId, name)
243
+ await this.printSuccessTips(envId)
244
+ } catch (e) {
245
+ loading.stop()
246
+ throw e
247
+ }
248
+ return
249
+ }
250
+ }
251
+
252
+ throw e
253
+ }
254
+
255
+ @InjectParams()
256
+ async printSuccessTips(envId: string, @Log() log?: Logger) {
257
+ let url = `https://console.cloud.tencent.com/tcb/scf?envId=${envId}`
258
+ const region = await getRegion()
259
+ url += `&rid=${regionIdMap[region]}`
260
+ const link = genClickableLink(url)
261
+ log.breakLine()
262
+ log.info(`控制台查看函数详情或创建HTTP 访问服务链接 🔗:${link}`)
263
+ log.info(`使用 ${highlightCommand('cloudbase functions:list')} 命令查看已部署云函数`)
264
+ }
265
+
266
+ // 创建函数 API 网关
267
+ async genApiGateway(envId: string, name: string) {
268
+ const loading = loadingFactory()
269
+ // 检查是否绑定了 HTTP 网关
270
+ const res = await queryGateway({
271
+ name,
272
+ envId
273
+ })
274
+ // 未开启,不生成 HTTP 调用了链接
275
+ if (res?.EnableService === false) return
276
+ loading.start('生成云函数HTTP 访问服务中...')
277
+
278
+ let path
279
+ if (res?.APISet?.length > 0) {
280
+ path = res.APISet[0]?.Path
281
+ } else {
282
+ path = `/${random(12)}`
283
+ await createGateway({
284
+ envId,
285
+ name,
286
+ path
287
+ })
288
+ }
289
+ loading.stop()
290
+ const link = genClickableLink(`https://${envId}.service.tcloudbase.com${path}`)
291
+ console.log(`\n云函数HTTP 访问服务链接:${link}`)
292
+ }
293
+ }