clever-tools 4.4.1 → 4.5.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 (291) hide show
  1. package/bin/clever.js +208 -2125
  2. package/package.json +33 -25
  3. package/src/commands/README.md +65 -0
  4. package/src/commands/accesslogs/accesslogs.command.js +158 -0
  5. package/src/commands/accesslogs/accesslogs.docs.md +20 -0
  6. package/src/commands/{activity.js → activity/activity.command.js} +74 -44
  7. package/src/commands/activity/activity.docs.md +19 -0
  8. package/src/commands/addon/addon.args.js +14 -0
  9. package/src/commands/addon/addon.command.js +7 -0
  10. package/src/commands/addon/addon.create.command.js +236 -0
  11. package/src/commands/addon/addon.delete.command.js +32 -0
  12. package/src/commands/addon/addon.docs.md +156 -0
  13. package/src/commands/addon/addon.env.command.js +50 -0
  14. package/src/commands/addon/addon.list.command.js +55 -0
  15. package/src/commands/addon/addon.providers.command.js +45 -0
  16. package/src/commands/addon/addon.providers.show.command.js +99 -0
  17. package/src/commands/addon/addon.rename.command.js +24 -0
  18. package/src/commands/applications/applications.command.js +59 -0
  19. package/src/commands/applications/applications.docs.md +31 -0
  20. package/src/commands/applications/applications.list.command.js +100 -0
  21. package/src/commands/cancel-deploy/cancel-deploy.command.js +30 -0
  22. package/src/commands/cancel-deploy/cancel-deploy.docs.md +16 -0
  23. package/src/commands/config/config.args.js +10 -0
  24. package/src/commands/config/config.command.js +20 -0
  25. package/src/commands/config/config.docs.md +86 -0
  26. package/src/commands/config/config.get.command.js +21 -0
  27. package/src/commands/config/config.set.command.js +38 -0
  28. package/src/commands/config/config.update.command.js +88 -0
  29. package/src/commands/console/console.command.js +31 -0
  30. package/src/commands/console/console.docs.md +16 -0
  31. package/src/commands/create/create.command.js +173 -0
  32. package/src/commands/create/create.docs.md +27 -0
  33. package/src/commands/{curl.js → curl/curl.command.js} +10 -3
  34. package/src/commands/curl/curl.docs.md +9 -0
  35. package/src/commands/database/database.args.js +8 -0
  36. package/src/commands/database/database.backups.command.js +60 -0
  37. package/src/commands/database/database.backups.download.command.js +55 -0
  38. package/src/commands/database/database.command.js +10 -0
  39. package/src/commands/database/database.docs.md +52 -0
  40. package/src/commands/delete/delete.command.js +43 -0
  41. package/src/commands/delete/delete.docs.md +17 -0
  42. package/src/commands/deploy/deploy.command.js +166 -0
  43. package/src/commands/deploy/deploy.docs.md +22 -0
  44. package/src/commands/diag/diag.command.js +136 -0
  45. package/src/commands/diag/diag.docs.md +15 -0
  46. package/src/commands/domain/domain.add.command.js +25 -0
  47. package/src/commands/domain/domain.args.js +8 -0
  48. package/src/commands/domain/domain.command.js +38 -0
  49. package/src/commands/domain/domain.diag.command.js +204 -0
  50. package/src/commands/domain/domain.docs.md +143 -0
  51. package/src/commands/domain/domain.favourite.command.js +35 -0
  52. package/src/commands/domain/domain.favourite.set.command.js +24 -0
  53. package/src/commands/domain/domain.favourite.unset.command.js +23 -0
  54. package/src/commands/domain/domain.overview.command.js +157 -0
  55. package/src/commands/domain/domain.rm.command.js +25 -0
  56. package/src/commands/drain/drain.args.js +8 -0
  57. package/src/commands/drain/drain.command.js +56 -0
  58. package/src/commands/drain/drain.create.command.js +128 -0
  59. package/src/commands/drain/drain.disable.command.js +27 -0
  60. package/src/commands/drain/drain.docs.md +129 -0
  61. package/src/commands/drain/drain.enable.command.js +27 -0
  62. package/src/commands/drain/drain.get.command.js +38 -0
  63. package/src/commands/drain/drain.remove.command.js +26 -0
  64. package/src/commands/emails/emails.add.command.js +32 -0
  65. package/src/commands/emails/emails.args.js +8 -0
  66. package/src/commands/emails/emails.command.js +35 -0
  67. package/src/commands/emails/emails.docs.md +79 -0
  68. package/src/commands/emails/emails.open.command.js +15 -0
  69. package/src/commands/emails/emails.primary.command.js +29 -0
  70. package/src/commands/emails/emails.remove-all.command.js +54 -0
  71. package/src/commands/emails/emails.remove.command.js +25 -0
  72. package/src/commands/env/env.command.js +77 -0
  73. package/src/commands/env/env.docs.md +99 -0
  74. package/src/commands/env/env.import-vars.command.js +45 -0
  75. package/src/commands/env/env.import.command.js +29 -0
  76. package/src/commands/env/env.rm.command.js +25 -0
  77. package/src/commands/env/env.set.command.js +32 -0
  78. package/src/commands/features/features.args.js +9 -0
  79. package/src/commands/features/features.command.js +7 -0
  80. package/src/commands/features/features.disable.command.js +25 -0
  81. package/src/commands/features/features.docs.md +71 -0
  82. package/src/commands/features/features.enable.command.js +32 -0
  83. package/src/commands/features/features.info.command.js +27 -0
  84. package/src/commands/features/features.list.command.js +49 -0
  85. package/src/commands/global.args.js +45 -0
  86. package/src/commands/global.commands.js +461 -0
  87. package/src/commands/global.options.js +186 -0
  88. package/src/commands/help/help.command.js +9 -0
  89. package/src/commands/help/help.docs.md +9 -0
  90. package/src/commands/k8s/k8s.add-persistent-storage.command.js +39 -0
  91. package/src/commands/k8s/k8s.args.js +9 -0
  92. package/src/commands/k8s/k8s.command.js +12 -0
  93. package/src/commands/k8s/k8s.create.command.js +86 -0
  94. package/src/commands/k8s/k8s.delete.command.js +40 -0
  95. package/src/commands/k8s/k8s.docs.md +131 -0
  96. package/src/commands/k8s/k8s.get-kubeconfig.command.js +32 -0
  97. package/src/commands/k8s/k8s.get.command.js +43 -0
  98. package/src/commands/k8s/k8s.list.command.js +38 -0
  99. package/src/commands/keycloak/keycloak.command.js +17 -0
  100. package/src/commands/keycloak/keycloak.disable-ng.command.js +13 -0
  101. package/src/commands/keycloak/keycloak.docs.md +197 -0
  102. package/src/commands/keycloak/keycloak.enable-ng.command.js +13 -0
  103. package/src/commands/keycloak/keycloak.get.command.js +17 -0
  104. package/src/commands/keycloak/keycloak.open.command.js +13 -0
  105. package/src/commands/keycloak/keycloak.open.logs.command.js +13 -0
  106. package/src/commands/keycloak/keycloak.open.webui.command.js +13 -0
  107. package/src/commands/keycloak/keycloak.rebuild.command.js +13 -0
  108. package/src/commands/keycloak/keycloak.restart.command.js +13 -0
  109. package/src/commands/keycloak/keycloak.version.check.command.js +17 -0
  110. package/src/commands/keycloak/keycloak.version.command.js +17 -0
  111. package/src/commands/keycloak/keycloak.version.update.command.js +17 -0
  112. package/src/commands/kv/kv.command.js +99 -0
  113. package/src/commands/kv/kv.docs.md +27 -0
  114. package/src/commands/link/link.command.js +31 -0
  115. package/src/commands/link/link.docs.md +22 -0
  116. package/src/commands/{login.js → login/login.command.js} +44 -22
  117. package/src/commands/login/login.docs.md +16 -0
  118. package/src/commands/logout/logout.command.js +15 -0
  119. package/src/commands/logout/logout.docs.md +9 -0
  120. package/src/commands/logs/logs.command.js +81 -0
  121. package/src/commands/logs/logs.docs.md +22 -0
  122. package/src/commands/make-default/make-default.command.js +17 -0
  123. package/src/commands/make-default/make-default.docs.md +15 -0
  124. package/src/commands/matomo/matomo.command.js +17 -0
  125. package/src/commands/matomo/matomo.docs.md +109 -0
  126. package/src/commands/matomo/matomo.get.command.js +17 -0
  127. package/src/commands/matomo/matomo.open.command.js +13 -0
  128. package/src/commands/matomo/matomo.open.logs.command.js +13 -0
  129. package/src/commands/matomo/matomo.open.webui.command.js +13 -0
  130. package/src/commands/matomo/matomo.rebuild.command.js +13 -0
  131. package/src/commands/matomo/matomo.restart.command.js +13 -0
  132. package/src/commands/metabase/metabase.command.js +17 -0
  133. package/src/commands/metabase/metabase.docs.md +169 -0
  134. package/src/commands/metabase/metabase.get.command.js +17 -0
  135. package/src/commands/metabase/metabase.open.command.js +13 -0
  136. package/src/commands/metabase/metabase.open.logs.command.js +13 -0
  137. package/src/commands/metabase/metabase.open.webui.command.js +13 -0
  138. package/src/commands/metabase/metabase.rebuild.command.js +13 -0
  139. package/src/commands/metabase/metabase.restart.command.js +13 -0
  140. package/src/commands/metabase/metabase.version.check.command.js +17 -0
  141. package/src/commands/metabase/metabase.version.command.js +17 -0
  142. package/src/commands/metabase/metabase.version.update.command.js +17 -0
  143. package/src/commands/ng/ng.args.js +27 -0
  144. package/src/commands/ng/ng.command.js +45 -0
  145. package/src/commands/ng/ng.create.command.js +60 -0
  146. package/src/commands/ng/ng.create.external.command.js +44 -0
  147. package/src/commands/ng/ng.delete.command.js +22 -0
  148. package/src/commands/ng/ng.delete.external.command.js +25 -0
  149. package/src/commands/ng/ng.docs.md +214 -0
  150. package/src/commands/ng/ng.get-config.command.js +32 -0
  151. package/src/commands/ng/ng.get.command.js +22 -0
  152. package/src/commands/ng/ng.link.command.js +25 -0
  153. package/src/commands/ng/ng.options.js +9 -0
  154. package/src/commands/ng/ng.search.command.js +22 -0
  155. package/src/commands/ng/ng.unlink.command.js +25 -0
  156. package/src/commands/notify-email/notify-email.add.command.js +65 -0
  157. package/src/commands/notify-email/notify-email.command.js +61 -0
  158. package/src/commands/notify-email/notify-email.docs.md +60 -0
  159. package/src/commands/notify-email/notify-email.remove.command.js +24 -0
  160. package/src/commands/open/open.command.js +24 -0
  161. package/src/commands/open/open.docs.md +16 -0
  162. package/src/commands/otoroshi/otoroshi.command.js +17 -0
  163. package/src/commands/otoroshi/otoroshi.disable-ng.command.js +13 -0
  164. package/src/commands/otoroshi/otoroshi.docs.md +211 -0
  165. package/src/commands/otoroshi/otoroshi.enable-ng.command.js +13 -0
  166. package/src/commands/otoroshi/otoroshi.get-config.command.js +13 -0
  167. package/src/commands/otoroshi/otoroshi.get.command.js +17 -0
  168. package/src/commands/otoroshi/otoroshi.open.command.js +13 -0
  169. package/src/commands/otoroshi/otoroshi.open.logs.command.js +13 -0
  170. package/src/commands/otoroshi/otoroshi.open.webui.command.js +13 -0
  171. package/src/commands/otoroshi/otoroshi.rebuild.command.js +13 -0
  172. package/src/commands/otoroshi/otoroshi.restart.command.js +13 -0
  173. package/src/commands/otoroshi/otoroshi.version.check.command.js +17 -0
  174. package/src/commands/otoroshi/otoroshi.version.command.js +17 -0
  175. package/src/commands/otoroshi/otoroshi.version.update.command.js +17 -0
  176. package/src/commands/profile/profile.command.js +60 -0
  177. package/src/commands/profile/profile.docs.md +23 -0
  178. package/src/commands/profile/profile.open.command.js +12 -0
  179. package/src/commands/published-config/published-config.command.js +40 -0
  180. package/src/commands/published-config/published-config.docs.md +77 -0
  181. package/src/commands/published-config/published-config.import.command.js +29 -0
  182. package/src/commands/published-config/published-config.rm.command.js +27 -0
  183. package/src/commands/published-config/published-config.set.command.js +34 -0
  184. package/src/commands/restart/restart.command.js +77 -0
  185. package/src/commands/restart/restart.docs.md +21 -0
  186. package/src/commands/scale/scale.command.js +121 -0
  187. package/src/commands/scale/scale.docs.md +23 -0
  188. package/src/commands/service/service.command.js +91 -0
  189. package/src/commands/service/service.docs.md +104 -0
  190. package/src/commands/service/service.link-addon.command.js +24 -0
  191. package/src/commands/service/service.link-app.command.js +23 -0
  192. package/src/commands/service/service.unlink-addon.command.js +24 -0
  193. package/src/commands/service/service.unlink-app.command.js +23 -0
  194. package/src/commands/ssh/ssh.command.js +40 -0
  195. package/src/commands/ssh/ssh.docs.md +17 -0
  196. package/src/commands/ssh-keys/ssh-keys.add.command.js +41 -0
  197. package/src/commands/ssh-keys/ssh-keys.args.js +8 -0
  198. package/src/commands/ssh-keys/ssh-keys.command.js +50 -0
  199. package/src/commands/ssh-keys/ssh-keys.docs.md +66 -0
  200. package/src/commands/ssh-keys/ssh-keys.open.command.js +12 -0
  201. package/src/commands/ssh-keys/ssh-keys.remove-all.command.js +54 -0
  202. package/src/commands/ssh-keys/ssh-keys.remove.command.js +26 -0
  203. package/src/commands/status/status.command.js +122 -0
  204. package/src/commands/status/status.docs.md +17 -0
  205. package/src/commands/stop/stop.command.js +23 -0
  206. package/src/commands/stop/stop.docs.md +16 -0
  207. package/src/commands/tcp-redirs/tcp-redirs.add.command.js +24 -0
  208. package/src/commands/tcp-redirs/tcp-redirs.command.js +41 -0
  209. package/src/commands/tcp-redirs/tcp-redirs.docs.md +71 -0
  210. package/src/commands/tcp-redirs/tcp-redirs.list-namespaces.command.js +48 -0
  211. package/src/commands/tcp-redirs/tcp-redirs.options.js +11 -0
  212. package/src/commands/tcp-redirs/tcp-redirs.remove.command.js +34 -0
  213. package/src/commands/tokens/tokens.command.js +43 -0
  214. package/src/commands/tokens/tokens.create.command.js +108 -0
  215. package/src/commands/tokens/tokens.docs.md +50 -0
  216. package/src/commands/tokens/tokens.revoke.command.js +25 -0
  217. package/src/commands/unlink/unlink.command.js +21 -0
  218. package/src/commands/unlink/unlink.docs.md +15 -0
  219. package/src/commands/version/version.command.js +13 -0
  220. package/src/commands/version/version.docs.md +9 -0
  221. package/src/commands/webhooks/webhooks.add.command.js +51 -0
  222. package/src/commands/webhooks/webhooks.command.js +57 -0
  223. package/src/commands/webhooks/webhooks.docs.md +61 -0
  224. package/src/commands/webhooks/webhooks.remove.command.js +24 -0
  225. package/src/lib/cliparse-patched.js +192 -0
  226. package/src/lib/define-argument.js +7 -0
  227. package/src/lib/define-argument.types.d.ts +23 -0
  228. package/src/lib/define-command.js +7 -0
  229. package/src/lib/define-command.types.d.ts +85 -0
  230. package/src/lib/define-common.types.d.ts +18 -0
  231. package/src/lib/define-option.js +7 -0
  232. package/src/lib/define-option.types.d.ts +29 -0
  233. package/src/lib/get-command-info.js +86 -0
  234. package/src/lib/get-command-info.types.d.ts +42 -0
  235. package/src/lib/zod-utils.js +66 -0
  236. package/src/models/addon.js +2 -3
  237. package/src/models/application.js +4 -5
  238. package/src/models/application_configuration.js +5 -23
  239. package/src/models/domain.js +34 -2
  240. package/src/models/exit-strategy-option.js +0 -9
  241. package/src/models/git.js +1 -4
  242. package/src/models/log-v4.js +5 -0
  243. package/src/models/log.js +5 -0
  244. package/src/models/namespaces.js +1 -2
  245. package/src/models/notification.js +1 -7
  246. package/src/parsers.js +33 -92
  247. package/src/command-options.js +0 -55
  248. package/src/command-promise-handler.js +0 -16
  249. package/src/commands/accesslogs.js +0 -138
  250. package/src/commands/addon.js +0 -391
  251. package/src/commands/applications.js +0 -123
  252. package/src/commands/cancel-deploy.js +0 -19
  253. package/src/commands/config.js +0 -47
  254. package/src/commands/console.js +0 -20
  255. package/src/commands/create.js +0 -129
  256. package/src/commands/database.js +0 -73
  257. package/src/commands/delete.js +0 -24
  258. package/src/commands/deploy.js +0 -133
  259. package/src/commands/diag.js +0 -126
  260. package/src/commands/domain.js +0 -445
  261. package/src/commands/drain.js +0 -164
  262. package/src/commands/emails.js +0 -156
  263. package/src/commands/env.js +0 -124
  264. package/src/commands/features.js +0 -87
  265. package/src/commands/k8s.js +0 -193
  266. package/src/commands/keycloak.js +0 -138
  267. package/src/commands/kv.js +0 -93
  268. package/src/commands/link.js +0 -20
  269. package/src/commands/logout.js +0 -8
  270. package/src/commands/logs.js +0 -45
  271. package/src/commands/makeDefault.js +0 -11
  272. package/src/commands/matomo.js +0 -85
  273. package/src/commands/metabase.js +0 -112
  274. package/src/commands/ng.js +0 -202
  275. package/src/commands/notify-email.js +0 -99
  276. package/src/commands/open.js +0 -13
  277. package/src/commands/otoroshi.js +0 -149
  278. package/src/commands/profile.js +0 -55
  279. package/src/commands/published-config.js +0 -70
  280. package/src/commands/restart.js +0 -52
  281. package/src/commands/scale.js +0 -66
  282. package/src/commands/service.js +0 -105
  283. package/src/commands/ssh-keys.js +0 -144
  284. package/src/commands/ssh.js +0 -20
  285. package/src/commands/status.js +0 -115
  286. package/src/commands/stop.js +0 -12
  287. package/src/commands/tcp-redirs.js +0 -80
  288. package/src/commands/tokens.js +0 -144
  289. package/src/commands/unlink.js +0 -14
  290. package/src/commands/version.js +0 -6
  291. package/src/commands/webhooks.js +0 -74
@@ -11,7 +11,6 @@ import {
11
11
  } from '@clevercloud/client/esm/api/v2/application.js';
12
12
  import { getAvailableInstances } from '@clevercloud/client/esm/api/v2/product.js';
13
13
  import { getSummary } from '@clevercloud/client/esm/api/v2/user.js';
14
- import cliparse from 'cliparse';
15
14
  import _ from 'lodash';
16
15
  import { confirmAnswer } from '../lib/prompts.js';
17
16
  import { styleText } from '../lib/style-text.js';
@@ -23,7 +22,7 @@ import { sendToApi } from './send-to-api.js';
23
22
  import * as User from './user.js';
24
23
 
25
24
  export function listAvailableTypes() {
26
- return cliparse.autocomplete.words([
25
+ return [
27
26
  'docker',
28
27
  'elixir',
29
28
  'frankenphp',
@@ -46,17 +45,17 @@ export function listAvailableTypes() {
46
45
  'static-apache',
47
46
  'v',
48
47
  'war',
49
- ]);
48
+ ];
50
49
  }
51
50
 
52
51
  export const AVAILABLE_ZONES = ['par', 'parhds', 'grahds', 'rbx', 'rbxhds', 'scw', 'ldn', 'mtl', 'sgp', 'syd', 'wsw'];
53
52
 
54
53
  export function listAvailableZones() {
55
- return cliparse.autocomplete.words(AVAILABLE_ZONES);
54
+ return AVAILABLE_ZONES;
56
55
  }
57
56
 
58
57
  export function listAvailableAliases() {
59
- return AppConfiguration.loadApplicationConf().then(({ apps }) => cliparse.autocomplete.words(_.map(apps, 'alias')));
58
+ return AppConfiguration.loadApplicationConf().then(({ apps }) => _.map(apps, 'alias'));
60
59
  }
61
60
 
62
61
  export function listAvailableFlavors() {
@@ -1,4 +1,3 @@
1
- import cliparse from 'cliparse';
2
1
  import dedent from 'dedent';
3
2
  import { Logger } from '../logger.js';
4
3
 
@@ -80,29 +79,12 @@ export function parse(config, value) {
80
79
  }
81
80
  }
82
81
 
83
- export function getUpdateOptions() {
84
- return CONFIG_KEYS.map((config) => getConfigOptions(config)).reduce((a, b) => [...a, ...b], []);
85
- }
86
-
87
- function getConfigOptions(config) {
88
- switch (config.kind) {
89
- case 'bool':
90
- case 'inverted-bool':
91
- case 'force-https':
92
- case 'task': {
93
- return [
94
- cliparse.flag(`enable-${config.id}`, { description: `Enable ${config.id}` }),
95
- cliparse.flag(`disable-${config.id}`, { description: `Disable ${config.id}` }),
96
- ];
97
- }
98
- default: {
99
- return [cliparse.option(`${config.id}`, { description: `Set ${config.id}` })];
100
- }
101
- }
102
- }
103
-
104
82
  export function parseOptions(options) {
105
- const newOptions = CONFIG_KEYS.map((config) => parseConfigOption(config, options)).filter((a) => a != null);
83
+ const newOptions = CONFIG_KEYS.map((config) => {
84
+ return parseConfigOption(config, options);
85
+ }).filter((a) => {
86
+ return a != null && a[1] != null;
87
+ });
106
88
  return Object.fromEntries(newOptions);
107
89
  }
108
90
 
@@ -1,11 +1,15 @@
1
- import { getAllDomains, getFavouriteDomain } from '@clevercloud/client/esm/api/v2/application.js';
1
+ import {
2
+ getAllDomains,
3
+ getFavouriteDomain as getFavouriteDomainWithError,
4
+ } from '@clevercloud/client/esm/api/v2/application.js';
2
5
  import _ from 'lodash';
6
+ import { parse as parseDomain } from 'tldts';
3
7
  import { Logger } from '../logger.js';
4
8
  import { sendToApi } from './send-to-api.js';
5
9
 
6
10
  export async function getBest(appId, orgaId) {
7
11
  Logger.debug('Trying to get the favourite vhost for ' + appId);
8
- return getFavouriteDomain({ id: orgaId, appId })
12
+ return getFavouriteDomainWithError({ id: orgaId, appId })
9
13
  .then(sendToApi)
10
14
  .catch(async (e) => {
11
15
  if (e.response.status !== 404) {
@@ -35,3 +39,31 @@ export function selectBest(vhosts) {
35
39
  });
36
40
  return customVhost || withoutDefaultDomain || vhosts[0];
37
41
  }
42
+
43
+ export function getFavouriteDomain({ ownerId, appId }) {
44
+ return getFavouriteDomainWithError({ id: ownerId, appId })
45
+ .then(sendToApi)
46
+ .then(({ fqdn }) => fqdn)
47
+ .catch((error) => {
48
+ if (error.id === 4021) {
49
+ // No favourite vhost
50
+ return null;
51
+ }
52
+ throw error;
53
+ });
54
+ }
55
+
56
+ export function getDomainObject(domainWithPathPrefix, favouriteDomain) {
57
+ const parsed = parseDomain(domainWithPathPrefix, { validateHostname: false });
58
+ return {
59
+ domainWithPathPrefix,
60
+ domain: parsed.domain,
61
+ domainWithoutSuffix: parsed.domainWithoutSuffix,
62
+ hostname: parsed.hostname,
63
+ publicSuffix: parsed.publicSuffix,
64
+ subdomain: parsed.subdomain,
65
+ isApex: parsed.subdomain === '',
66
+ pathPrefix: new URL('https://' + domainWithPathPrefix).pathname,
67
+ isFavourite: domainWithPathPrefix === favouriteDomain,
68
+ };
69
+ }
@@ -1,17 +1,8 @@
1
- import { styleText } from '../lib/style-text.js';
2
- import { Logger } from '../logger.js';
3
-
4
1
  export function get(follow, exitOnDeploy) {
5
2
  if (follow) {
6
3
  if (exitOnDeploy === 'deploy-start') {
7
4
  throw new Error('The `follow` and `exit-on` set to "deploy-start" options are not compatible');
8
5
  }
9
- Logger.println(
10
- styleText(
11
- 'yellow',
12
- 'The `follow` option is deprecated and will be removed in an upcoming major, use --exit-on set to "never" instead',
13
- ),
14
- );
15
6
  return 'never';
16
7
  }
17
8
  return exitOnDeploy;
package/src/models/git.js CHANGED
@@ -1,4 +1,3 @@
1
- import cliparse from 'cliparse';
2
1
  import * as git from 'isomorphic-git';
3
2
  import _ from 'lodash';
4
3
  import fs from 'node:fs';
@@ -111,9 +110,7 @@ export async function push(remoteUrl, branchRefspec, force) {
111
110
  }
112
111
 
113
112
  export function completeBranches() {
114
- return getRepo()
115
- .then((repo) => git.listBranches(repo))
116
- .then(cliparse.autocomplete.words);
113
+ return getRepo().then((repo) => git.listBranches(repo));
117
114
  }
118
115
 
119
116
  export async function isShallow() {
@@ -133,6 +133,11 @@ export async function watchDeploymentAndDisplayLogs(options) {
133
133
  logsStream.close(quiet ? 'quiet' : 'follow');
134
134
  }
135
135
 
136
+ // deploymentEnded can be undefined if deferred resolved (e.g., stream closed via SIGINT)
137
+ if (deploymentEnded == null) {
138
+ return;
139
+ }
140
+
136
141
  if (deploymentEnded.state === 'OK') {
137
142
  Logger.println('');
138
143
 
package/src/models/log.js CHANGED
@@ -133,6 +133,11 @@ export async function watchDeploymentAndDisplayLogs({
133
133
  logsStream.close();
134
134
  }
135
135
 
136
+ // deploymentEnded can be undefined if deferred resolved (e.g., stream closed via SIGINT)
137
+ if (deploymentEnded == null) {
138
+ return;
139
+ }
140
+
136
141
  if (deploymentEnded.state === 'OK') {
137
142
  Logger.println(styleText(['bold', 'green'], 'Deployment successful'));
138
143
  } else if (deploymentEnded.state === 'CANCELLED') {
@@ -1,5 +1,4 @@
1
1
  import { getNamespaces as getTcpRedirNamespaces } from '@clevercloud/client/esm/api/v2/organisation.js';
2
- import cliparse from 'cliparse';
3
2
  import * as Application from './application.js';
4
3
  import { sendToApi } from './send-to-api.js';
5
4
 
@@ -11,5 +10,5 @@ export async function completeNamespaces() {
11
10
  // Sadly we do not have access to current params in complete as of now
12
11
  const { ownerId } = await Application.resolveId(null, null);
13
12
 
14
- return getNamespaces(ownerId).then(cliparse.autocomplete.words);
13
+ return getNamespaces(ownerId);
15
14
  }
@@ -1,15 +1,9 @@
1
- import cliparse from 'cliparse';
2
1
  import * as AppConfig from './app_configuration.js';
3
2
  import * as Organisation from './organisation.js';
4
3
  import * as User from './user.js';
5
4
 
6
5
  export function listMetaEvents() {
7
- return cliparse.autocomplete.words([
8
- 'META_SERVICE_LIFECYCLE',
9
- 'META_DEPLOYMENT_RESULT',
10
- 'META_SERVICE_MANAGEMENT',
11
- 'META_CREDITS',
12
- ]);
6
+ return ['META_SERVICE_LIFECYCLE', 'META_DEPLOYMENT_RESULT', 'META_SERVICE_MANAGEMENT', 'META_CREDITS'];
13
7
  }
14
8
 
15
9
  export function getOrgaIdOrUserId(orgIdOrName) {
package/src/parsers.js CHANGED
@@ -1,4 +1,3 @@
1
- import cliparse from 'cliparse';
2
1
  import ISO8601 from 'iso8601-duration';
3
2
  import * as Application from './models/application.js';
4
3
  import { NG_MEMBER_PREFIXES } from './models/ng.js';
@@ -9,92 +8,63 @@ export function addonOptions(options) {
9
8
  const optionsArray = typeof options === 'string' ? [options] : options;
10
9
  for (const option of optionsArray) {
11
10
  if (!option.match(addonOptionsRegex)) {
12
- return cliparse.parsers.error('Invalid option: ' + option);
11
+ throw new Error('Invalid option: ' + option);
13
12
  }
14
13
  }
15
- return cliparse.parsers.success(optionsArray.join(','));
14
+ return optionsArray.join(',');
16
15
  }
17
16
 
18
17
  export function flavor(flavor) {
19
18
  const flavors = Application.listAvailableFlavors();
20
19
  if (flavors.includes(flavor)) {
21
- return cliparse.parsers.success(flavor);
20
+ return flavor;
22
21
  }
23
- return cliparse.parsers.error('Invalid value: ' + flavor);
22
+ throw new Error('Invalid value: ' + flavor);
24
23
  }
25
24
 
26
25
  export function buildFlavor(flavorOrDisabled) {
27
26
  if (flavorOrDisabled === 'disabled') {
28
- return cliparse.parsers.success(flavorOrDisabled);
27
+ return flavorOrDisabled;
29
28
  }
30
29
  return flavor(flavorOrDisabled);
31
30
  }
32
31
 
33
- export function instances(instances) {
34
- const parsedInstances = parseInt(instances, 10);
35
- if (isNaN(parsedInstances)) {
36
- return cliparse.parsers.error('Invalid number: ' + instances);
37
- }
38
- if (parsedInstances < 1 || parsedInstances > 20) {
39
- return cliparse.parsers.error('The number of instances must be between 1 and 20');
40
- }
41
- return cliparse.parsers.success(parsedInstances);
42
- }
43
-
44
32
  export function date(dateString) {
45
33
  const date = new Date(dateString);
46
34
  if (isNaN(dateString) && !isNaN(date.getTime())) {
47
- return cliparse.parsers.success(date);
48
- }
49
-
50
- const duration = durationInSeconds(dateString);
51
- if (duration.success) {
52
- return cliparse.parsers.success(new Date(Date.now() - duration.success * 1000));
35
+ return date;
53
36
  }
54
37
 
55
- return duration;
38
+ const seconds = durationInSeconds(dateString);
39
+ return new Date(Date.now() - seconds * 1000);
56
40
  }
57
41
 
58
42
  export function futureDateOrDuration(dateString) {
59
43
  const date = new Date(dateString);
60
44
  if (isNaN(dateString) && !isNaN(date.getTime())) {
61
- return cliparse.parsers.success(date);
45
+ return date;
62
46
  }
63
47
 
64
- const duration = durationInSeconds(dateString);
65
- if (duration.success) {
66
- return cliparse.parsers.success(new Date(Date.now() + duration.success * 1000));
67
- }
68
-
69
- return duration;
70
- }
71
-
72
- // This simple regex is enough for our use cases
73
- const emailRegex = /^\S+@\S+\.\S+$/g;
74
-
75
- export function email(string) {
76
- if (string.match(emailRegex)) {
77
- return cliparse.parsers.success(string);
78
- }
79
- return cliparse.parsers.error('Invalid email');
48
+ const seconds = durationInSeconds(dateString);
49
+ return new Date(Date.now() + seconds * 1000);
80
50
  }
81
51
 
82
52
  const appIdRegex = /^app_[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
83
53
 
84
54
  export function appIdOrName(string) {
85
55
  if (string.match(appIdRegex)) {
86
- return cliparse.parsers.success({ app_id: string });
56
+ return { app_id: string };
87
57
  }
88
- return cliparse.parsers.success({ app_name: string });
58
+ return { app_name: string };
89
59
  }
90
60
 
91
61
  const orgaIdRegex = /^(user_|orga_)[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
92
62
 
93
63
  export function orgaIdOrName(string) {
94
64
  if (string.match(orgaIdRegex)) {
95
- return cliparse.parsers.success({ orga_id: string });
65
+ return { orga_id: string };
96
66
  }
97
- return cliparse.parsers.success({ orga_name: string });
67
+ return { orga_name: string };
98
68
  }
99
69
 
100
70
  const addonIdRegex = /^addon_[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
@@ -104,31 +74,16 @@ const ulidRegex = /^(kubernetes)_[0-9A-HJ-NP-TV-Z]{26}$/i;
104
74
 
105
75
  export function addonIdOrName(string) {
106
76
  if (string.match(addonIdRegex)) {
107
- return cliparse.parsers.success({ addon_id: string });
77
+ return { addon_id: string };
108
78
  }
109
79
  if (string.match(operatorIdRegex) || string.match(ulidRegex)) {
110
- return cliparse.parsers.success({ operator_id: string });
80
+ return { operator_id: string };
111
81
  }
112
- return cliparse.parsers.success({ addon_name: string });
82
+ return { addon_name: string };
113
83
  }
114
84
 
115
85
  export function commaSeparated(string) {
116
- return cliparse.parsers.success(string.split(','));
117
- }
118
-
119
- export function integer(string) {
120
- const integer = parseInt(string);
121
- if (isNaN(integer)) {
122
- return cliparse.parsers.error('Invalid number: ' + string);
123
- }
124
- return cliparse.parsers.success(integer);
125
- }
126
-
127
- export function nonEmptyString(string) {
128
- if (typeof string !== 'string' || string === '') {
129
- return cliparse.parsers.error('Invalid string, it should not be empty');
130
- }
131
- return cliparse.parsers.success(string);
86
+ return string.split(',');
132
87
  }
133
88
 
134
89
  // /^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?$/i;
@@ -136,22 +91,20 @@ const tagRegex = /^[^,\s]+$/;
136
91
 
137
92
  export function tag(string) {
138
93
  if (string.match(tagRegex)) {
139
- return cliparse.parsers.success(string);
94
+ return string;
140
95
  }
141
- return cliparse.parsers.error(`Invalid tag '${string}'. Should match ${tagRegex}`);
96
+ throw new Error(`Invalid tag '${string}'. Should match ${tagRegex}`);
142
97
  }
143
98
 
144
99
  export function tags(string) {
145
100
  if (String(string).length === 0) {
146
- return cliparse.parsers.success([]);
101
+ return [];
147
102
  }
148
103
  const tags = String(string).split(',');
149
104
  for (const current of tags) {
150
- if (tag(current).error) {
151
- return cliparse.parsers.error(`Invalid tag '${current}'. Should match \`${tagRegex}\``);
152
- }
105
+ tag(current); // will throw if invalid
153
106
  }
154
- return cliparse.parsers.success(tags);
107
+ return tags;
155
108
  }
156
109
 
157
110
  /**
@@ -161,29 +114,25 @@ export function tags(string) {
161
114
  * @returns {number} number of seconds
162
115
  */
163
116
  export function durationInSeconds(durationStr = '') {
164
- const failed = cliparse.parsers.error(
165
- `Invalid duration: "${durationStr}", expect (IS0 8601 duration / a "1h, 1m, 30s" like duration / a positive number in seconds)`,
166
- );
117
+ const errorMessage = `Invalid duration: "${durationStr}", expect (IS0 8601 duration / a "1h, 1m, 30s" like duration / a positive number in seconds)`;
167
118
 
168
119
  if (durationStr.startsWith('P')) {
169
120
  try {
170
121
  const d = ISO8601.parse(durationStr);
171
- return cliparse.parsers.success(ISO8601.toSeconds(d));
122
+ return ISO8601.toSeconds(d);
172
123
  } catch {
173
- return failed;
124
+ throw new Error(errorMessage);
174
125
  }
175
126
  }
176
127
 
177
128
  try {
178
- const durationInSeconds = parseSimpleDuration(durationStr);
179
- return cliparse.parsers.success(durationInSeconds);
129
+ return parseSimpleDuration(durationStr);
180
130
  } catch {
181
131
  const n = Number.parseInt(durationStr);
182
132
  if (isNaN(n) || n < 0) {
183
- return failed;
133
+ throw new Error(errorMessage);
184
134
  }
185
-
186
- return cliparse.parsers.success(n);
135
+ return n;
187
136
  }
188
137
  }
189
138
 
@@ -211,18 +160,10 @@ function parseSimpleDuration(durationStr) {
211
160
  // Network Groups parsers
212
161
  export function ngResourceType(string) {
213
162
  if (string.startsWith('ng_')) {
214
- return cliparse.parsers.success({ ngId: string });
163
+ return { ngId: string };
215
164
  }
216
165
  if (Object.keys(NG_MEMBER_PREFIXES).some((prefix) => string.startsWith(prefix))) {
217
- return cliparse.parsers.success({ memberId: string });
218
- }
219
- return cliparse.parsers.success({ ngResourceLabel: string });
220
- }
221
-
222
- export function ngValidType(string) {
223
- if (string === 'NetworkGroup' || string === 'Member' || string === 'CleverPeer' || string === 'ExternalPeer') {
224
- return cliparse.parsers.success(string);
225
- } else {
226
- return cliparse.parsers.error(`Invalid Network Group resource type: ${string}`);
166
+ return { memberId: string };
227
167
  }
168
+ return { ngResourceLabel: string };
228
169
  }
@@ -1,55 +0,0 @@
1
- import cliparse from 'cliparse';
2
-
3
- export function getOutputFormatOption(formats = []) {
4
- const availableFormats = ['human', 'json', ...formats];
5
- return cliparse.option('format', {
6
- aliases: ['F'],
7
- metavar: 'format',
8
- parser: (format) => {
9
- return availableFormats.includes(format)
10
- ? cliparse.parsers.success(format)
11
- : cliparse.parsers.error('The output format must be one of ' + availableFormats.join(', '));
12
- },
13
- default: 'human',
14
- description: `Output format (${availableFormats.join(', ')})`,
15
- complete() {
16
- return cliparse.autocomplete.words(availableFormats);
17
- },
18
- });
19
- }
20
-
21
- export function getSameCommitPolicyOption() {
22
- const availablePolicies = ['error', 'ignore', 'restart', 'rebuild'];
23
- return cliparse.option('same-commit-policy', {
24
- aliases: ['p'],
25
- metavar: 'policy',
26
- parser: (policy) => {
27
- return availablePolicies.includes(policy)
28
- ? cliparse.parsers.success(policy)
29
- : cliparse.parsers.error(`the policy must be one of ${availablePolicies.join(', ')}`);
30
- },
31
- default: 'error',
32
- description: `What to do when local and remote commit are identical (${availablePolicies.join(', ')})`,
33
- complete() {
34
- return cliparse.autocomplete.words(availablePolicies);
35
- },
36
- });
37
- }
38
-
39
- export function getExitOnOption() {
40
- const availableExitOn = ['deploy-start', 'deploy-end', 'never'];
41
- return cliparse.option('exit-on', {
42
- aliases: ['e'],
43
- metavar: 'step',
44
- parser: (exitOnStrategy) => {
45
- return availableExitOn.includes(exitOnStrategy)
46
- ? cliparse.parsers.success(exitOnStrategy)
47
- : cliparse.parsers.error(`The exit-on strategy must be one of ${availableExitOn.join(', ')}`);
48
- },
49
- default: 'deploy-end',
50
- description: `Step at which the logs streaming is ended, steps are: ${availableExitOn.join(', ')}`,
51
- complete() {
52
- return cliparse.autocomplete.words(availableExitOn);
53
- },
54
- });
55
- }
@@ -1,16 +0,0 @@
1
- import semver from 'semver';
2
- import pkg from '../package.json' with { type: 'json' };
3
- import { Logger } from './logger.js';
4
-
5
- export function handleCommandPromise(promise) {
6
- promise.catch((error) => {
7
- Logger.error(error);
8
- const semverIsOk = semver.satisfies(process.version, pkg.engines.node);
9
- if (!semverIsOk) {
10
- Logger.warn(
11
- `You are using node ${process.version}, some of our commands require node ${pkg.engines.node}. The error may be caused by this.`,
12
- );
13
- }
14
- process.exit(1);
15
- });
16
- }
@@ -1,138 +0,0 @@
1
- import { ApplicationAccessLogStream } from '@clevercloud/client/esm/streams/access-logs.js';
2
- import { formatTable } from '../format-table.js';
3
- import { styleText } from '../lib/style-text.js';
4
- import { Logger } from '../logger.js';
5
- import * as Application from '../models/application.js';
6
- import { JsonArray } from '../models/json-array.js';
7
- import { getHostAndTokens } from '../models/send-to-api.js';
8
- import { truncateWithEllipsis } from '../models/utils.js';
9
-
10
- // 2000 logs per 100ms maximum
11
- const THROTTLE_ELEMENTS = 2000;
12
- const THROTTLE_PER_IN_MILLISECONDS = 100;
13
- const CITY_MAX_LENGTH = 20;
14
-
15
- export async function accessLogs(params) {
16
- // TODO: drop when add-ons are supported in API
17
- if (params.options.addon) {
18
- throw new Error('Access Logs are not available for add-ons yet');
19
- }
20
-
21
- const { apiHost, tokens } = await getHostAndTokens();
22
- const { alias, app: appIdOrName, format, before: until, after: since } = params.options;
23
- const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
24
-
25
- const stream = new ApplicationAccessLogStream({
26
- apiHost,
27
- tokens,
28
- ownerId,
29
- appId,
30
- since,
31
- until,
32
- throttleElements: THROTTLE_ELEMENTS,
33
- throttlePerInMilliseconds: THROTTLE_PER_IN_MILLISECONDS,
34
- });
35
-
36
- if (format === 'human') {
37
- Logger.println(styleText('yellow', '/!\\ This feature is in Beta testing phase'));
38
- }
39
-
40
- if (format === 'json' && !until) {
41
- throw new Error('JSON format only works with a limiting parameter such as `before`');
42
- }
43
-
44
- // used for 'json' format
45
- const jsonArray = new JsonArray();
46
-
47
- stream
48
- .on('open', () => {
49
- Logger.debug(styleText('blue', `Logs stream (open) ${JSON.stringify({ appId })}`));
50
- if (format === 'json') {
51
- jsonArray.open();
52
- }
53
- })
54
- .on('error', (event) => {
55
- Logger.debug(styleText('red', `Logs stream (error) ${event.error.message}`));
56
- })
57
- .onLog((log) => {
58
- switch (format) {
59
- case 'json':
60
- jsonArray.push(log);
61
- break;
62
- case 'json-stream':
63
- Logger.printJson(log);
64
- break;
65
- case 'human':
66
- default:
67
- // when the connection is cut too early, or for TCP redirections, we don't have HTTP section
68
- if (log.http == null) {
69
- break;
70
- }
71
-
72
- Logger.println(formatHuman(log));
73
- break;
74
- }
75
- });
76
-
77
- // Properly close the stream
78
- process.once('SIGINT', (signal) => stream.close(signal));
79
-
80
- const closeReason = await stream.start();
81
-
82
- if (format === 'json') {
83
- jsonArray.close();
84
- }
85
-
86
- Logger.debug(`stream closed: ${closeReason?.type}`);
87
- }
88
-
89
- function formatHuman(log) {
90
- const { date, http, source } = log;
91
- const country = source.countryCode ?? '(unknown)';
92
- const hasSourceCity = source.city ?? '';
93
-
94
- return formatTable(
95
- [
96
- [
97
- styleText('grey', date.toISOString(date)),
98
- source.ip,
99
- `${country}${hasSourceCity ? '/' + truncateWithEllipsis(CITY_MAX_LENGTH, source.city) : ''}`,
100
- colorStatusCode(http.response.statusCode),
101
- http.request.method.toString().padEnd(4, ' ') + ' ' + http.request.path,
102
- ],
103
- ],
104
- ACCESSLOG_COLUMN_WIDTHS,
105
- );
106
- }
107
-
108
- const ACCESSLOG_COLUMN_WIDTHS = [
109
- '2024-06-24T08:05:43.880Z',
110
- '255.255.255.255',
111
- // country / city
112
- 2 + 1 + CITY_MAX_LENGTH,
113
- 'XXX',
114
- // longest method name
115
- 'OPTIONS',
116
- // path
117
- ];
118
-
119
- /**
120
- * @param {number} code
121
- * @returns {string}
122
- */
123
- function colorStatusCode(code) {
124
- const codeString = code.toString();
125
- if (code >= 500) {
126
- return styleText('red', codeString);
127
- }
128
- if (code >= 400) {
129
- return styleText('yellow', codeString);
130
- }
131
- if (code >= 300) {
132
- return styleText('blue', codeString);
133
- }
134
- if (code >= 200) {
135
- return styleText('green', codeString);
136
- }
137
- return codeString;
138
- }