@cloudbase/cli 1.12.7-alpha.4 → 2.0.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.
Files changed (317) 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/.vscode/settings.json +3 -0
  7. package/LICENSE +5 -5
  8. package/README.md +35 -35
  9. package/bin/cloudbase.js +5 -5
  10. package/bin/tcb.js +0 -0
  11. package/changelog.md +6 -6
  12. package/jest.config.js +17 -17
  13. package/lib/commands/account/login.js +18 -18
  14. package/lib/commands/run/create.js +6 -1
  15. package/lib/commands/run/delete.js +6 -1
  16. package/lib/commands/run/image/common.js +1 -1
  17. package/lib/commands/run/image/delete.js +5 -0
  18. package/lib/commands/run/image/download.js +5 -0
  19. package/lib/commands/run/image/list.js +5 -0
  20. package/lib/commands/run/image/upload.js +5 -0
  21. package/lib/commands/run/index.js +1 -0
  22. package/lib/commands/run/list.js +7 -1
  23. package/lib/commands/run/service/config.js +112 -0
  24. package/lib/commands/run/service/create.js +140 -0
  25. package/lib/commands/run/service/deploy.js +145 -0
  26. package/lib/commands/run/service/index.js +21 -0
  27. package/lib/commands/run/service/list.js +115 -0
  28. package/lib/commands/run/service/update.js +132 -0
  29. package/lib/commands/run/version/common.js +1 -1
  30. package/lib/commands/run/version/create.js +5 -0
  31. package/lib/commands/run/version/delete.js +5 -0
  32. package/lib/commands/run/version/list.js +5 -0
  33. package/lib/commands/run/version/modify.js +5 -0
  34. package/lib/commands/run/version/update.js +5 -0
  35. package/lib/commands/storage/storage.js +1 -1
  36. package/lib/constant.js +20 -1
  37. package/lib/env/login.js +7 -7
  38. package/lib/help.js +40 -38
  39. package/lib/run/index.js +1 -0
  40. package/lib/run/service/common.js +163 -0
  41. package/lib/run/service/config.js +70 -0
  42. package/lib/run/service/create.js +67 -0
  43. package/lib/run/service/deployPackage.js +87 -0
  44. package/lib/run/service/index.js +23 -0
  45. package/lib/run/service/list.js +31 -0
  46. package/lib/run/service/showLogs.js +116 -0
  47. package/lib/run/service/update.js +83 -0
  48. package/lib/utils/checkTcbrEnv.js +74 -0
  49. package/lib/utils/commonParamsCheck.js +48 -0
  50. package/lib/utils/index.js +3 -0
  51. package/lib/utils/tcbrApi/callTcbrApi.js +38 -0
  52. package/lib/utils/tcbrApi/index.js +17 -0
  53. package/lib/utils/tcbrApi/tcbr-cloud-api/cloud-api-service.js +268 -0
  54. package/lib/utils/tcbrApi/tcbr-cloud-api/error.js +17 -0
  55. package/lib/utils/tcbrApi/tcbr-cloud-api/index.js +17 -0
  56. package/lib/utils/tcbrApi/tcbr-cloud-api/request.js +40 -0
  57. package/lib/utils/tcbrApi/tcbr-cloud-api-request.js +61 -0
  58. package/lib/utils/validator.js +32 -1
  59. package/package.json +88 -88
  60. package/post-install.js +61 -61
  61. package/runtime/nodejs/bootstrap.js +255 -255
  62. package/runtime/nodejs/runtime.js +183 -183
  63. package/src/auth/index.ts +1 -1
  64. package/src/auth/login.ts +91 -91
  65. package/src/auth/logout.ts +7 -7
  66. package/src/commands/account/index.ts +2 -2
  67. package/src/commands/account/login.ts +192 -192
  68. package/src/commands/account/logout.ts +24 -24
  69. package/src/commands/common.ts +246 -246
  70. package/src/commands/env/base.ts +90 -90
  71. package/src/commands/env/create.ts +92 -92
  72. package/src/commands/env/domain.ts +186 -186
  73. package/src/commands/env/index.ts +4 -4
  74. package/src/commands/env/login.ts +235 -235
  75. package/src/commands/framework/index.ts +124 -124
  76. package/src/commands/functions/alias/getRoute.ts +76 -76
  77. package/src/commands/functions/alias/index.ts +2 -2
  78. package/src/commands/functions/alias/setRoute.ts +82 -82
  79. package/src/commands/functions/code-download.ts +100 -100
  80. package/src/commands/functions/code-update.ts +62 -62
  81. package/src/commands/functions/concurrency/delete.ts +45 -45
  82. package/src/commands/functions/concurrency/index.ts +2 -2
  83. package/src/commands/functions/concurrency/list.ts +58 -58
  84. package/src/commands/functions/concurrency/set.ts +47 -47
  85. package/src/commands/functions/config-update.ts +76 -76
  86. package/src/commands/functions/copy.ts +62 -62
  87. package/src/commands/functions/delete.ts +79 -79
  88. package/src/commands/functions/deploy.ts +293 -293
  89. package/src/commands/functions/detail.ts +138 -138
  90. package/src/commands/functions/index.ts +16 -16
  91. package/src/commands/functions/invoke.ts +121 -121
  92. package/src/commands/functions/layer/bind.ts +182 -182
  93. package/src/commands/functions/layer/common.ts +8 -8
  94. package/src/commands/functions/layer/create.ts +49 -49
  95. package/src/commands/functions/layer/delete.ts +73 -73
  96. package/src/commands/functions/layer/download.ts +92 -92
  97. package/src/commands/functions/layer/index.ts +7 -7
  98. package/src/commands/functions/layer/list.ts +94 -94
  99. package/src/commands/functions/layer/sort.ts +76 -76
  100. package/src/commands/functions/list.ts +68 -68
  101. package/src/commands/functions/log.ts +148 -148
  102. package/src/commands/functions/run.ts +249 -249
  103. package/src/commands/functions/trigger-create.ts +79 -79
  104. package/src/commands/functions/trigger-delete.ts +105 -105
  105. package/src/commands/functions/version/index.ts +1 -1
  106. package/src/commands/functions/version/list.ts +73 -73
  107. package/src/commands/functions/version/publish.ts +43 -43
  108. package/src/commands/gateway/create.ts +109 -109
  109. package/src/commands/gateway/delete.ts +81 -81
  110. package/src/commands/gateway/domain.ts +159 -159
  111. package/src/commands/gateway/index.ts +5 -5
  112. package/src/commands/gateway/list.ts +76 -76
  113. package/src/commands/gateway/switch.ts +107 -107
  114. package/src/commands/helpers/index.ts +2 -2
  115. package/src/commands/helpers/init.ts +431 -431
  116. package/src/commands/helpers/new.ts +117 -117
  117. package/src/commands/helpers/open.ts +67 -67
  118. package/src/commands/hosting/hosting.ts +360 -360
  119. package/src/commands/index.ts +13 -13
  120. package/src/commands/lowcode/app.ts +34 -34
  121. package/src/commands/lowcode/comps.ts +322 -322
  122. package/src/commands/lowcode/index.ts +1 -1
  123. package/src/commands/lowcode/utils.ts +24 -24
  124. package/src/commands/run/create.ts +9 -2
  125. package/src/commands/run/delete.ts +8 -2
  126. package/src/commands/run/image/common.ts +1 -1
  127. package/src/commands/run/image/delete.ts +8 -1
  128. package/src/commands/run/image/download.ts +7 -1
  129. package/src/commands/run/image/index.ts +4 -4
  130. package/src/commands/run/image/list.ts +7 -2
  131. package/src/commands/run/image/upload.ts +8 -1
  132. package/src/commands/run/index.ts +2 -1
  133. package/src/commands/run/list.ts +11 -3
  134. package/src/commands/run/service/config.ts +81 -0
  135. package/src/commands/run/service/create.ts +118 -0
  136. package/src/commands/run/service/deploy.ts +121 -0
  137. package/src/commands/run/service/index.ts +5 -0
  138. package/src/commands/run/service/list.ts +94 -0
  139. package/src/commands/run/service/update.ts +104 -0
  140. package/src/commands/run/standalonegateway/common.ts +7 -7
  141. package/src/commands/run/standalonegateway/create.ts +85 -85
  142. package/src/commands/run/standalonegateway/destroy.ts +59 -59
  143. package/src/commands/run/standalonegateway/index.ts +4 -4
  144. package/src/commands/run/standalonegateway/list.ts +53 -53
  145. package/src/commands/run/standalonegateway/package.ts +62 -62
  146. package/src/commands/run/standalonegateway/turn.ts +63 -63
  147. package/src/commands/run/version/common.ts +1 -1
  148. package/src/commands/run/version/create.ts +8 -1
  149. package/src/commands/run/version/delete.ts +8 -2
  150. package/src/commands/run/version/index.ts +4 -4
  151. package/src/commands/run/version/list.ts +7 -1
  152. package/src/commands/run/version/modify.ts +8 -1
  153. package/src/commands/run/version/update.ts +8 -1
  154. package/src/commands/smart.ts +132 -132
  155. package/src/commands/storage/storage.ts +464 -464
  156. package/src/commands/third/thirdAttach.ts +49 -49
  157. package/src/completion/index.ts +13 -13
  158. package/src/constant.ts +35 -1
  159. package/src/decorators/captureError.ts +25 -25
  160. package/src/decorators/constants.ts +12 -12
  161. package/src/decorators/deprecate.ts +25 -25
  162. package/src/decorators/guard.ts +42 -42
  163. package/src/decorators/index.ts +7 -7
  164. package/src/decorators/injectParams.ts +54 -54
  165. package/src/decorators/params/common.ts +28 -28
  166. package/src/decorators/params/index.ts +35 -35
  167. package/src/env/domain.ts +33 -33
  168. package/src/env/index.ts +63 -63
  169. package/src/env/login.ts +80 -80
  170. package/src/error.ts +36 -36
  171. package/src/function/alias.ts +43 -43
  172. package/src/function/base.ts +253 -253
  173. package/src/function/code.ts +55 -55
  174. package/src/function/concurrency.ts +57 -57
  175. package/src/function/create.ts +78 -78
  176. package/src/function/delete.ts +42 -42
  177. package/src/function/index.ts +10 -10
  178. package/src/function/layer/attach.ts +68 -68
  179. package/src/function/layer/create.ts +63 -63
  180. package/src/function/layer/delete.ts +21 -21
  181. package/src/function/layer/download.ts +54 -54
  182. package/src/function/layer/index.ts +7 -7
  183. package/src/function/layer/list.ts +32 -32
  184. package/src/function/layer/sort.ts +24 -24
  185. package/src/function/trigger.ts +97 -97
  186. package/src/function/update.ts +35 -35
  187. package/src/function/version.ts +38 -38
  188. package/src/function/vpc.ts +22 -22
  189. package/src/gateway/index.ts +137 -137
  190. package/src/help.ts +50 -48
  191. package/src/hosting.ts +212 -212
  192. package/src/index.ts +13 -13
  193. package/src/logger.ts +17 -17
  194. package/src/run/create.ts +23 -23
  195. package/src/run/delete.ts +15 -15
  196. package/src/run/image/build.ts +36 -36
  197. package/src/run/image/delete.ts +13 -13
  198. package/src/run/image/index.ts +3 -3
  199. package/src/run/image/info.ts +26 -26
  200. package/src/run/index.ts +2 -1
  201. package/src/run/list.ts +29 -29
  202. package/src/run/repo.ts +24 -24
  203. package/src/run/service/common.ts +206 -0
  204. package/src/run/service/config.ts +77 -0
  205. package/src/run/service/create.ts +52 -0
  206. package/src/run/service/deployPackage.ts +63 -0
  207. package/src/run/service/index.ts +7 -0
  208. package/src/run/service/list.ts +29 -0
  209. package/src/run/service/showLogs.ts +98 -0
  210. package/src/run/service/update.ts +81 -0
  211. package/src/run/standalonegateway/create.ts +24 -24
  212. package/src/run/standalonegateway/destroy.ts +19 -19
  213. package/src/run/standalonegateway/index.ts +4 -4
  214. package/src/run/standalonegateway/list.ts +74 -74
  215. package/src/run/standalonegateway/package/list.ts +24 -24
  216. package/src/run/standalonegateway/turn/index.ts +1 -1
  217. package/src/run/standalonegateway/turn/off.ts +19 -19
  218. package/src/run/standalonegateway/turn/on.ts +19 -19
  219. package/src/run/version/create.ts +68 -68
  220. package/src/run/version/delete.ts +15 -15
  221. package/src/run/version/index.ts +5 -5
  222. package/src/run/version/list.ts +16 -16
  223. package/src/run/version/modify.ts +16 -16
  224. package/src/run/version/repo.ts +27 -27
  225. package/src/run/version/update.ts +58 -58
  226. package/src/storage.ts +114 -114
  227. package/src/third/index.ts +12 -12
  228. package/src/types.ts +128 -2
  229. package/src/utils/auth.ts +15 -15
  230. package/src/utils/checkTcbrEnv.ts +67 -0
  231. package/src/utils/cli-table.ts +23 -23
  232. package/src/utils/commonParamsCheck.ts +65 -0
  233. package/src/utils/config.ts +39 -39
  234. package/src/utils/env.ts +244 -244
  235. package/src/utils/fs/del.ts +5 -5
  236. package/src/utils/fs/index.ts +71 -71
  237. package/src/utils/function-packer.ts +97 -97
  238. package/src/utils/index.ts +5 -1
  239. package/src/utils/log.ts +81 -81
  240. package/src/utils/net/cloud-api-request.ts +62 -62
  241. package/src/utils/net/credential.ts +53 -53
  242. package/src/utils/net/http-request.ts +84 -84
  243. package/src/utils/net/index.ts +4 -4
  244. package/src/utils/net/manager-service.ts +36 -36
  245. package/src/utils/net/proxy.ts +6 -6
  246. package/src/utils/notice.ts +28 -28
  247. package/src/utils/output/highlight.ts +5 -5
  248. package/src/utils/output/index.ts +2 -2
  249. package/src/utils/output/link.ts +10 -10
  250. package/src/utils/output/loading.ts +82 -82
  251. package/src/utils/parallel.ts +82 -82
  252. package/src/utils/platform/index.ts +2 -2
  253. package/src/utils/platform/mac.ts +21 -21
  254. package/src/utils/platform/os.ts +64 -64
  255. package/src/utils/platform/port.ts +10 -10
  256. package/src/utils/progress-bar.ts +38 -38
  257. package/src/utils/prompt/select.ts +59 -59
  258. package/src/utils/reporter/agree.ts +20 -20
  259. package/src/utils/reporter/download.ts +26 -26
  260. package/src/utils/reporter/index.ts +3 -3
  261. package/src/utils/reporter/usage.ts +20 -20
  262. package/src/utils/store/auth.ts +49 -49
  263. package/src/utils/store/common.ts +8 -8
  264. package/src/utils/store/db.ts +68 -68
  265. package/src/utils/store/index.ts +4 -4
  266. package/src/utils/store/usage.ts +12 -12
  267. package/src/utils/tcbrApi/callTcbrApi.ts +28 -0
  268. package/src/utils/tcbrApi/index.ts +1 -0
  269. package/src/utils/tcbrApi/tcbr-cloud-api/cloud-api-service.ts +363 -0
  270. package/src/utils/tcbrApi/tcbr-cloud-api/error.ts +30 -0
  271. package/src/utils/tcbrApi/tcbr-cloud-api/index.ts +1 -0
  272. package/src/utils/tcbrApi/tcbr-cloud-api/request.ts +28 -0
  273. package/src/utils/tcbrApi/tcbr-cloud-api-request.ts +66 -0
  274. package/src/utils/template.ts +170 -170
  275. package/src/utils/tools/encoding.ts +8 -8
  276. package/src/utils/tools/index.ts +4 -4
  277. package/src/utils/tools/object.ts +33 -33
  278. package/src/utils/tools/time.ts +38 -38
  279. package/src/utils/tools/uid.ts +19 -19
  280. package/src/utils/validator.ts +64 -32
  281. package/templates/html/loginFail.html +90 -90
  282. package/templates/html/loginSuccess.html +86 -86
  283. package/templates/server/node/_gitignore +54 -54
  284. package/templates/server/node/cloudbaserc.json +10 -10
  285. package/templates/server/node/index.js +5 -5
  286. package/templates/server/node/package.json +9 -9
  287. package/tsconfig.json +19 -19
  288. package/tsconfig.test.json +13 -13
  289. package/types/commands/run/index.d.ts +1 -0
  290. package/types/commands/run/service/config.d.ts +14 -0
  291. package/types/commands/run/service/create.d.ts +13 -0
  292. package/types/commands/run/service/deploy.d.ts +13 -0
  293. package/types/commands/run/service/index.d.ts +5 -0
  294. package/types/commands/run/service/list.d.ts +13 -0
  295. package/types/commands/run/service/update.d.ts +13 -0
  296. package/types/constant.d.ts +18 -0
  297. package/types/run/index.d.ts +1 -0
  298. package/types/run/service/common.d.ts +32 -0
  299. package/types/run/service/config.d.ts +23 -0
  300. package/types/run/service/create.d.ts +7 -0
  301. package/types/run/service/deployPackage.d.ts +11 -0
  302. package/types/run/service/index.d.ts +7 -0
  303. package/types/run/service/list.d.ts +2 -0
  304. package/types/run/service/showLogs.d.ts +2 -0
  305. package/types/run/service/update.d.ts +2 -0
  306. package/types/types.d.ts +116 -2
  307. package/types/utils/checkTcbrEnv.d.ts +3 -0
  308. package/types/utils/commonParamsCheck.d.ts +3 -0
  309. package/types/utils/index.d.ts +3 -0
  310. package/types/utils/tcbrApi/callTcbrApi.d.ts +1 -0
  311. package/types/utils/tcbrApi/index.d.ts +1 -0
  312. package/types/utils/tcbrApi/tcbr-cloud-api/cloud-api-service.d.ts +51 -0
  313. package/types/utils/tcbrApi/tcbr-cloud-api/error.d.ts +20 -0
  314. package/types/utils/tcbrApi/tcbr-cloud-api/index.d.ts +1 -0
  315. package/types/utils/tcbrApi/tcbr-cloud-api/request.d.ts +4 -0
  316. package/types/utils/tcbrApi/tcbr-cloud-api-request.d.ts +9 -0
  317. package/types/utils/validator.d.ts +4 -0
@@ -1,360 +1,360 @@
1
- import fs from 'fs'
2
- import path from 'path'
3
- import inquirer from 'inquirer'
4
- import logSymbols from 'log-symbols'
5
- import { HostingService } from '@cloudbase/manager-node/types/hosting'
6
-
7
- import { Command, ICommand } from '../common'
8
-
9
- import {
10
- getHostingInfo,
11
- hostingDeploy,
12
- hostingDelete,
13
- hostingList,
14
- walkLocalDir
15
- } from '../../hosting'
16
- import { CloudBaseError } from '../../error'
17
- import {
18
- isDirectory,
19
- loadingFactory,
20
- printHorizontalTable,
21
- formatDate,
22
- formateFileSize,
23
- createUploadProgressBar,
24
- genClickableLink,
25
- checkFullAccess,
26
- getMangerService
27
- } from '../../utils'
28
-
29
- import { InjectParams, EnvId, ArgsParams, ArgsOptions, Log, Logger } from '../../decorators'
30
-
31
- const HostingStatusMap = {
32
- init: '初始化中',
33
- process: '处理中',
34
- online: '已上线',
35
- destroying: '销毁中',
36
- offline: '已下线',
37
- create_fail: '初始化失败', // eslint-disable-line
38
- destroy_fail: '销毁失败' // eslint-disable-line
39
- }
40
-
41
- async function getHostingService(envId: string): Promise<HostingService> {
42
- const { hosting } = await getMangerService(envId)
43
- return hosting
44
- }
45
-
46
- @ICommand()
47
- export class HostingDetail extends Command {
48
- get options() {
49
- return {
50
- cmd: 'hosting',
51
- childCmd: 'detail',
52
- deprecateCmd: 'hosting:detail',
53
- options: [
54
- {
55
- flags: '-e, --envId <envId>',
56
- desc: '环境 Id'
57
- }
58
- ],
59
- desc: '查看静态网站服务信息'
60
- }
61
- }
62
-
63
- @InjectParams()
64
- async execute(@EnvId() envId, @Log() log: Logger) {
65
- const res = await getHostingInfo({ envId })
66
-
67
- const website = res?.data?.[0]
68
-
69
- if (!website) {
70
- const link = genClickableLink('https://console.cloud.tencent.com/tcb')
71
- throw new CloudBaseError(
72
- `您还没有开启静态网站服务,请先到云开发控制台开启静态网站服务!\n 👉 ${link}`
73
- )
74
- }
75
-
76
- const link = genClickableLink(`https://${website.cdnDomain}`)
77
- // offline 状态不展示域名
78
- if (website.status !== 'offline') {
79
- log.info(`静态网站域名:${link}`)
80
- }
81
- log.info(`静态网站状态:【${HostingStatusMap[website.status]}】`)
82
- }
83
- }
84
-
85
- @ICommand()
86
- export class HostingDeploy extends Command {
87
- get options() {
88
- return {
89
- cmd: 'hosting',
90
- childCmd: 'deploy [filePath] [cloudPath]',
91
- deprecateCmd: 'hosting:deploy [filePath] [cloudPath]',
92
- options: [
93
- {
94
- flags: '-e, --envId <envId>',
95
- desc: '环境 Id'
96
- }
97
- ],
98
- desc: '部署静态网站文件'
99
- }
100
- }
101
-
102
- @InjectParams()
103
- async execute(@EnvId() envId, @ArgsParams() params, @Log() log: Logger) {
104
- const localPath = params?.[0] || '.'
105
- const cloudPath = params?.[1] || ''
106
-
107
- log.verbose('本地目录', localPath)
108
-
109
- const resolveLocalPath = path.resolve(localPath)
110
- checkFullAccess(resolveLocalPath, true)
111
- const isDir = isDirectory(resolveLocalPath)
112
-
113
- const loading = loadingFactory()
114
- loading.start('准备上传中...')
115
-
116
- let totalFiles = 0
117
-
118
- if (isDir) {
119
- let files = await walkLocalDir(envId, resolveLocalPath)
120
- files = files.filter((item) => !isDirectory(item))
121
- totalFiles = files.length
122
- }
123
-
124
- // 上传进度条
125
- const onProgress = createUploadProgressBar(
126
- () => {
127
- !isDir && log.success('文件部署成功!')
128
- },
129
- () => {
130
- loading.stop()
131
- }
132
- )
133
-
134
- const successFiles = []
135
- const failedFiles = []
136
-
137
- await hostingDeploy({
138
- filePath: resolveLocalPath,
139
- cloudPath,
140
- envId,
141
- isDir,
142
- onProgress,
143
- onFileFinish: (...args) => {
144
- const error = args[0]
145
- const fileInfo = (args as any)[2]
146
- if (error) {
147
- failedFiles.push(fileInfo.Key)
148
- } else {
149
- successFiles.push(fileInfo.Key)
150
- }
151
- }
152
- })
153
-
154
- const info = await getHostingInfo({
155
- envId
156
- })
157
-
158
- const website = info?.data?.[0]
159
-
160
- const link = genClickableLink(`https://${website.cdnDomain}`)
161
- log.success(`\n部署完成 👉 ${link}`)
162
-
163
- if (isDir) {
164
- log.success(`文件共计 ${totalFiles} 个`)
165
- log.success(`文件上传成功 ${successFiles.length} 个`)
166
- // 上传成功的文件
167
- if (totalFiles <= 50) {
168
- printHorizontalTable(
169
- ['状态', '文件'],
170
- successFiles.map((item) => [logSymbols.success, item])
171
- )
172
- }
173
-
174
- // 上传失败的文件
175
- log.error(`文件上传失败 ${failedFiles.length} 个`)
176
- if (failedFiles.length) {
177
- if (totalFiles <= 50) {
178
- printHorizontalTable(
179
- ['状态', '文件'],
180
- failedFiles.map((item) => [logSymbols.error, item])
181
- )
182
- } else {
183
- // 写入文件到本地
184
- const errorLogPath = path.resolve('./cloudbase-error.log')
185
- log.error('上传失败文件:')
186
- console.log(errorLogPath)
187
- fs.writeFileSync(errorLogPath, failedFiles.join('\n'))
188
- }
189
-
190
- // 抛出错误
191
- throw new CloudBaseError('部分文件上传失败,进程退出')
192
- }
193
- }
194
- }
195
- }
196
-
197
- @ICommand()
198
- export class HostingDeleteFiles extends Command {
199
- get options() {
200
- return {
201
- cmd: 'hosting',
202
- childCmd: 'delete [cloudPath]',
203
- deprecateCmd: 'hosting:delete [cloudPath]',
204
- options: [
205
- {
206
- flags: '-e, --envId <envId>',
207
- desc: '环境 Id'
208
- },
209
- {
210
- flags: '-d, --dir',
211
- desc: '删除目标是否为文件夹'
212
- }
213
- ],
214
- desc: '删除静态网站文件/文件夹,文件夹需指定 --dir 选项'
215
- }
216
- }
217
-
218
- @InjectParams()
219
- async execute(@EnvId() envId, @ArgsOptions() options, @ArgsParams() params) {
220
- const cloudPath = params?.[0] || ''
221
- let isDir = options.dir
222
-
223
- // 删除所有文件,危险操作,需要提示
224
- if (!cloudPath) {
225
- const { confirm } = await inquirer.prompt({
226
- type: 'confirm',
227
- name: 'confirm',
228
- message: '指定云端路径为空,将会删除所有文件,是否继续',
229
- default: false
230
- })
231
- if (!confirm) {
232
- throw new CloudBaseError('操作终止!')
233
- }
234
- isDir = true
235
- }
236
-
237
- // cloudPath 为 / 时,只能删除文件夹
238
- if (cloudPath === '/') {
239
- isDir = true
240
- }
241
-
242
- const fileText = isDir ? '文件夹' : '文件'
243
-
244
- const loading = loadingFactory()
245
- loading.start(`删除${fileText}中...`)
246
-
247
- try {
248
- await hostingDelete({
249
- envId,
250
- isDir,
251
- cloudPath
252
- })
253
- loading.succeed(`删除${fileText}成功!`)
254
- } catch (e) {
255
- loading.fail(`删除${fileText}失败!`)
256
- throw new CloudBaseError(e.message)
257
- }
258
- }
259
- }
260
-
261
- @ICommand()
262
- export class HostingList extends Command {
263
- get options() {
264
- return {
265
- cmd: 'hosting',
266
- childCmd: 'list',
267
- deprecateCmd: 'hosting:list',
268
- options: [
269
- {
270
- flags: '-e, --envId <envId>',
271
- desc: '环境 Id'
272
- }
273
- ],
274
- desc: '展示文件列表'
275
- }
276
- }
277
-
278
- @InjectParams()
279
- async execute(@EnvId() envId) {
280
- const loading = loadingFactory()
281
- loading.start('获取文件列表中...')
282
-
283
- try {
284
- const list = await hostingList({
285
- envId
286
- })
287
- loading.stop()
288
- const head = ['序号', 'Key', 'LastModified', 'ETag', 'Size(KB)']
289
- const notDir = (item) => !(Number(item.Size) === 0 && /\/$/g.test(item.Key))
290
- const tableData = list
291
- .filter(notDir)
292
- .map((item, index) => [
293
- index + 1,
294
- item.Key,
295
- formatDate(item.LastModified, 'yyyy-MM-dd hh:mm:ss'),
296
- item.ETag,
297
- String(formateFileSize(item.Size, 'KB'))
298
- ])
299
- printHorizontalTable(head, tableData)
300
- } catch (e) {
301
- loading.fail('获取文件列表失败!')
302
- throw new CloudBaseError(e.message)
303
- }
304
- }
305
- }
306
-
307
- @ICommand()
308
- export class HostingDownloadCommand extends Command {
309
- get options() {
310
- return {
311
- cmd: 'hosting',
312
- childCmd: 'download <cloudPath> [localPath]',
313
- options: [
314
- {
315
- flags: '-e, --envId <envId>',
316
- desc: '环境 Id'
317
- },
318
- {
319
- flags: '-d, --dir',
320
- desc: '下载目标是否为文件夹'
321
- }
322
- ],
323
- desc: '下载文件/文件夹,文件夹需指定 --dir 选项'
324
- }
325
- }
326
-
327
- @InjectParams()
328
- async execute(@EnvId() envId, @ArgsOptions() options, @ArgsParams() params) {
329
- let cloudPath: string = params?.[0]
330
- const localPath = params?.[1] || '.'
331
- const hostingService = await getHostingService(envId)
332
- const resolveLocalPath = path.resolve(localPath)
333
-
334
- const { dir } = options
335
- const fileText = dir ? '文件夹' : '文件'
336
-
337
- const loading = loadingFactory()
338
-
339
- loading.start(`下载${fileText}中`)
340
-
341
- // cloudPath 以 / 开头
342
- if (/^\/.+/.test(cloudPath)) {
343
- cloudPath = cloudPath.slice(1)
344
- }
345
-
346
- if (dir) {
347
- await hostingService.downloadDirectory({
348
- cloudPath,
349
- localPath: resolveLocalPath
350
- })
351
- } else {
352
- await hostingService.downloadFile({
353
- cloudPath,
354
- localPath: resolveLocalPath
355
- })
356
- }
357
-
358
- loading.succeed(`下载${fileText}成功!`)
359
- }
360
- }
1
+ import fs from 'fs'
2
+ import path from 'path'
3
+ import inquirer from 'inquirer'
4
+ import logSymbols from 'log-symbols'
5
+ import { HostingService } from '@cloudbase/manager-node/types/hosting'
6
+
7
+ import { Command, ICommand } from '../common'
8
+
9
+ import {
10
+ getHostingInfo,
11
+ hostingDeploy,
12
+ hostingDelete,
13
+ hostingList,
14
+ walkLocalDir
15
+ } from '../../hosting'
16
+ import { CloudBaseError } from '../../error'
17
+ import {
18
+ isDirectory,
19
+ loadingFactory,
20
+ printHorizontalTable,
21
+ formatDate,
22
+ formateFileSize,
23
+ createUploadProgressBar,
24
+ genClickableLink,
25
+ checkFullAccess,
26
+ getMangerService
27
+ } from '../../utils'
28
+
29
+ import { InjectParams, EnvId, ArgsParams, ArgsOptions, Log, Logger } from '../../decorators'
30
+
31
+ const HostingStatusMap = {
32
+ init: '初始化中',
33
+ process: '处理中',
34
+ online: '已上线',
35
+ destroying: '销毁中',
36
+ offline: '已下线',
37
+ create_fail: '初始化失败', // eslint-disable-line
38
+ destroy_fail: '销毁失败' // eslint-disable-line
39
+ }
40
+
41
+ async function getHostingService(envId: string): Promise<HostingService> {
42
+ const { hosting } = await getMangerService(envId)
43
+ return hosting
44
+ }
45
+
46
+ @ICommand()
47
+ export class HostingDetail extends Command {
48
+ get options() {
49
+ return {
50
+ cmd: 'hosting',
51
+ childCmd: 'detail',
52
+ deprecateCmd: 'hosting:detail',
53
+ options: [
54
+ {
55
+ flags: '-e, --envId <envId>',
56
+ desc: '环境 Id'
57
+ }
58
+ ],
59
+ desc: '查看静态网站服务信息'
60
+ }
61
+ }
62
+
63
+ @InjectParams()
64
+ async execute(@EnvId() envId, @Log() log: Logger) {
65
+ const res = await getHostingInfo({ envId })
66
+
67
+ const website = res?.data?.[0]
68
+
69
+ if (!website) {
70
+ const link = genClickableLink('https://console.cloud.tencent.com/tcb')
71
+ throw new CloudBaseError(
72
+ `您还没有开启静态网站服务,请先到云开发控制台开启静态网站服务!\n 👉 ${link}`
73
+ )
74
+ }
75
+
76
+ const link = genClickableLink(`https://${website.cdnDomain}`)
77
+ // offline 状态不展示域名
78
+ if (website.status !== 'offline') {
79
+ log.info(`静态网站域名:${link}`)
80
+ }
81
+ log.info(`静态网站状态:【${HostingStatusMap[website.status]}】`)
82
+ }
83
+ }
84
+
85
+ @ICommand()
86
+ export class HostingDeploy extends Command {
87
+ get options() {
88
+ return {
89
+ cmd: 'hosting',
90
+ childCmd: 'deploy [filePath] [cloudPath]',
91
+ deprecateCmd: 'hosting:deploy [filePath] [cloudPath]',
92
+ options: [
93
+ {
94
+ flags: '-e, --envId <envId>',
95
+ desc: '环境 Id'
96
+ }
97
+ ],
98
+ desc: '部署静态网站文件'
99
+ }
100
+ }
101
+
102
+ @InjectParams()
103
+ async execute(@EnvId() envId, @ArgsParams() params, @Log() log: Logger) {
104
+ const localPath = params?.[0] || '.'
105
+ const cloudPath = params?.[1] || ''
106
+
107
+ log.verbose('本地目录', localPath)
108
+
109
+ const resolveLocalPath = path.resolve(localPath)
110
+ checkFullAccess(resolveLocalPath, true)
111
+ const isDir = isDirectory(resolveLocalPath)
112
+
113
+ const loading = loadingFactory()
114
+ loading.start('准备上传中...')
115
+
116
+ let totalFiles = 0
117
+
118
+ if (isDir) {
119
+ let files = await walkLocalDir(envId, resolveLocalPath)
120
+ files = files.filter((item) => !isDirectory(item))
121
+ totalFiles = files.length
122
+ }
123
+
124
+ // 上传进度条
125
+ const onProgress = createUploadProgressBar(
126
+ () => {
127
+ !isDir && log.success('文件部署成功!')
128
+ },
129
+ () => {
130
+ loading.stop()
131
+ }
132
+ )
133
+
134
+ const successFiles = []
135
+ const failedFiles = []
136
+
137
+ await hostingDeploy({
138
+ filePath: resolveLocalPath,
139
+ cloudPath,
140
+ envId,
141
+ isDir,
142
+ onProgress,
143
+ onFileFinish: (...args) => {
144
+ const error = args[0]
145
+ const fileInfo = (args as any)[2]
146
+ if (error) {
147
+ failedFiles.push(fileInfo.Key)
148
+ } else {
149
+ successFiles.push(fileInfo.Key)
150
+ }
151
+ }
152
+ })
153
+
154
+ const info = await getHostingInfo({
155
+ envId
156
+ })
157
+
158
+ const website = info?.data?.[0]
159
+
160
+ const link = genClickableLink(`https://${website.cdnDomain}`)
161
+ log.success(`\n部署完成 👉 ${link}`)
162
+
163
+ if (isDir) {
164
+ log.success(`文件共计 ${totalFiles} 个`)
165
+ log.success(`文件上传成功 ${successFiles.length} 个`)
166
+ // 上传成功的文件
167
+ if (totalFiles <= 50) {
168
+ printHorizontalTable(
169
+ ['状态', '文件'],
170
+ successFiles.map((item) => [logSymbols.success, item])
171
+ )
172
+ }
173
+
174
+ // 上传失败的文件
175
+ log.error(`文件上传失败 ${failedFiles.length} 个`)
176
+ if (failedFiles.length) {
177
+ if (totalFiles <= 50) {
178
+ printHorizontalTable(
179
+ ['状态', '文件'],
180
+ failedFiles.map((item) => [logSymbols.error, item])
181
+ )
182
+ } else {
183
+ // 写入文件到本地
184
+ const errorLogPath = path.resolve('./cloudbase-error.log')
185
+ log.error('上传失败文件:')
186
+ console.log(errorLogPath)
187
+ fs.writeFileSync(errorLogPath, failedFiles.join('\n'))
188
+ }
189
+
190
+ // 抛出错误
191
+ throw new CloudBaseError('部分文件上传失败,进程退出')
192
+ }
193
+ }
194
+ }
195
+ }
196
+
197
+ @ICommand()
198
+ export class HostingDeleteFiles extends Command {
199
+ get options() {
200
+ return {
201
+ cmd: 'hosting',
202
+ childCmd: 'delete [cloudPath]',
203
+ deprecateCmd: 'hosting:delete [cloudPath]',
204
+ options: [
205
+ {
206
+ flags: '-e, --envId <envId>',
207
+ desc: '环境 Id'
208
+ },
209
+ {
210
+ flags: '-d, --dir',
211
+ desc: '删除目标是否为文件夹'
212
+ }
213
+ ],
214
+ desc: '删除静态网站文件/文件夹,文件夹需指定 --dir 选项'
215
+ }
216
+ }
217
+
218
+ @InjectParams()
219
+ async execute(@EnvId() envId, @ArgsOptions() options, @ArgsParams() params) {
220
+ const cloudPath = params?.[0] || ''
221
+ let isDir = options.dir
222
+
223
+ // 删除所有文件,危险操作,需要提示
224
+ if (!cloudPath) {
225
+ const { confirm } = await inquirer.prompt({
226
+ type: 'confirm',
227
+ name: 'confirm',
228
+ message: '指定云端路径为空,将会删除所有文件,是否继续',
229
+ default: false
230
+ })
231
+ if (!confirm) {
232
+ throw new CloudBaseError('操作终止!')
233
+ }
234
+ isDir = true
235
+ }
236
+
237
+ // cloudPath 为 / 时,只能删除文件夹
238
+ if (cloudPath === '/') {
239
+ isDir = true
240
+ }
241
+
242
+ const fileText = isDir ? '文件夹' : '文件'
243
+
244
+ const loading = loadingFactory()
245
+ loading.start(`删除${fileText}中...`)
246
+
247
+ try {
248
+ await hostingDelete({
249
+ envId,
250
+ isDir,
251
+ cloudPath
252
+ })
253
+ loading.succeed(`删除${fileText}成功!`)
254
+ } catch (e) {
255
+ loading.fail(`删除${fileText}失败!`)
256
+ throw new CloudBaseError(e.message)
257
+ }
258
+ }
259
+ }
260
+
261
+ @ICommand()
262
+ export class HostingList extends Command {
263
+ get options() {
264
+ return {
265
+ cmd: 'hosting',
266
+ childCmd: 'list',
267
+ deprecateCmd: 'hosting:list',
268
+ options: [
269
+ {
270
+ flags: '-e, --envId <envId>',
271
+ desc: '环境 Id'
272
+ }
273
+ ],
274
+ desc: '展示文件列表'
275
+ }
276
+ }
277
+
278
+ @InjectParams()
279
+ async execute(@EnvId() envId) {
280
+ const loading = loadingFactory()
281
+ loading.start('获取文件列表中...')
282
+
283
+ try {
284
+ const list = await hostingList({
285
+ envId
286
+ })
287
+ loading.stop()
288
+ const head = ['序号', 'Key', 'LastModified', 'ETag', 'Size(KB)']
289
+ const notDir = (item) => !(Number(item.Size) === 0 && /\/$/g.test(item.Key))
290
+ const tableData = list
291
+ .filter(notDir)
292
+ .map((item, index) => [
293
+ index + 1,
294
+ item.Key,
295
+ formatDate(item.LastModified, 'yyyy-MM-dd hh:mm:ss'),
296
+ item.ETag,
297
+ String(formateFileSize(item.Size, 'KB'))
298
+ ])
299
+ printHorizontalTable(head, tableData)
300
+ } catch (e) {
301
+ loading.fail('获取文件列表失败!')
302
+ throw new CloudBaseError(e.message)
303
+ }
304
+ }
305
+ }
306
+
307
+ @ICommand()
308
+ export class HostingDownloadCommand extends Command {
309
+ get options() {
310
+ return {
311
+ cmd: 'hosting',
312
+ childCmd: 'download <cloudPath> [localPath]',
313
+ options: [
314
+ {
315
+ flags: '-e, --envId <envId>',
316
+ desc: '环境 Id'
317
+ },
318
+ {
319
+ flags: '-d, --dir',
320
+ desc: '下载目标是否为文件夹'
321
+ }
322
+ ],
323
+ desc: '下载文件/文件夹,文件夹需指定 --dir 选项'
324
+ }
325
+ }
326
+
327
+ @InjectParams()
328
+ async execute(@EnvId() envId, @ArgsOptions() options, @ArgsParams() params) {
329
+ let cloudPath: string = params?.[0]
330
+ const localPath = params?.[1] || '.'
331
+ const hostingService = await getHostingService(envId)
332
+ const resolveLocalPath = path.resolve(localPath)
333
+
334
+ const { dir } = options
335
+ const fileText = dir ? '文件夹' : '文件'
336
+
337
+ const loading = loadingFactory()
338
+
339
+ loading.start(`下载${fileText}中`)
340
+
341
+ // cloudPath 以 / 开头
342
+ if (/^\/.+/.test(cloudPath)) {
343
+ cloudPath = cloudPath.slice(1)
344
+ }
345
+
346
+ if (dir) {
347
+ await hostingService.downloadDirectory({
348
+ cloudPath,
349
+ localPath: resolveLocalPath
350
+ })
351
+ } else {
352
+ await hostingService.downloadFile({
353
+ cloudPath,
354
+ localPath: resolveLocalPath
355
+ })
356
+ }
357
+
358
+ loading.succeed(`下载${fileText}成功!`)
359
+ }
360
+ }