clever-tools 3.13.1 → 4.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 (93) hide show
  1. package/README.md +130 -37
  2. package/bin/clever.js +1427 -718
  3. package/package.json +62 -77
  4. package/src/clever-client/auth-bridge.js +9 -12
  5. package/src/clever-client/ng.js +1 -1
  6. package/src/clever-client/operators.js +7 -7
  7. package/src/command-options.js +6 -6
  8. package/src/command-promise-handler.js +6 -6
  9. package/src/commands/accesslogs.js +38 -29
  10. package/src/commands/activity.js +62 -40
  11. package/src/commands/addon.js +65 -69
  12. package/src/commands/applications.js +33 -31
  13. package/src/commands/cancel-deploy.js +7 -7
  14. package/src/commands/config.js +9 -7
  15. package/src/commands/console.js +3 -3
  16. package/src/commands/create.js +33 -32
  17. package/src/commands/curl.js +14 -36
  18. package/src/commands/database.js +10 -30
  19. package/src/commands/delete.js +8 -8
  20. package/src/commands/deploy.js +60 -46
  21. package/src/commands/diag.js +27 -25
  22. package/src/commands/domain.js +89 -91
  23. package/src/commands/drain.js +26 -14
  24. package/src/commands/emails.js +24 -28
  25. package/src/commands/env.js +18 -18
  26. package/src/commands/features.js +12 -18
  27. package/src/commands/keycloak.js +11 -11
  28. package/src/commands/kv.js +13 -13
  29. package/src/commands/link.js +9 -8
  30. package/src/commands/login.js +19 -27
  31. package/src/commands/logout.js +1 -1
  32. package/src/commands/logs.js +20 -12
  33. package/src/commands/makeDefault.js +5 -5
  34. package/src/commands/matomo.js +7 -7
  35. package/src/commands/metabase.js +9 -9
  36. package/src/commands/ng.js +32 -32
  37. package/src/commands/notify-email.js +11 -15
  38. package/src/commands/open.js +1 -1
  39. package/src/commands/otoroshi.js +11 -11
  40. package/src/commands/profile.js +8 -8
  41. package/src/commands/published-config.js +11 -11
  42. package/src/commands/restart.js +15 -8
  43. package/src/commands/scale.js +25 -16
  44. package/src/commands/service.js +28 -11
  45. package/src/commands/ssh-keys.js +25 -29
  46. package/src/commands/ssh.js +1 -2
  47. package/src/commands/status.js +31 -22
  48. package/src/commands/stop.js +3 -3
  49. package/src/commands/tcp-redirs.js +27 -26
  50. package/src/commands/tokens.js +44 -43
  51. package/src/commands/unlink.js +7 -5
  52. package/src/commands/version.js +2 -4
  53. package/src/commands/webhooks.js +8 -10
  54. package/src/experimental-features.js +7 -5
  55. package/src/format-table.js +46 -15
  56. package/src/initial-setup.js +2 -32
  57. package/src/initial-update-notifier.js +18 -0
  58. package/src/lib/has-param.js +16 -0
  59. package/src/lib/ng-print.js +21 -24
  60. package/src/lib/operator-commands.js +58 -53
  61. package/src/lib/prompts.js +5 -5
  62. package/src/lib/slugify.js +1 -1
  63. package/src/logger.js +26 -21
  64. package/src/models/activity.js +3 -3
  65. package/src/models/addon.js +54 -56
  66. package/src/models/app_configuration.js +34 -32
  67. package/src/models/application.js +90 -77
  68. package/src/models/application_configuration.js +19 -27
  69. package/src/models/configuration.js +30 -32
  70. package/src/models/deployments.js +9 -19
  71. package/src/models/domain.js +10 -9
  72. package/src/models/drain.js +16 -15
  73. package/src/models/exit-strategy-option.js +15 -5
  74. package/src/models/fs-utils.js +4 -3
  75. package/src/models/git.js +26 -32
  76. package/src/models/ids-resolver.js +37 -41
  77. package/src/models/isomorphic-http-with-agent.js +3 -3
  78. package/src/models/json-array.js +5 -6
  79. package/src/models/log-v4.js +44 -52
  80. package/src/models/log.js +40 -45
  81. package/src/models/namespaces.js +4 -4
  82. package/src/models/ng-resources.js +49 -39
  83. package/src/models/ng.js +41 -40
  84. package/src/models/node-dns-resolver.js +3 -3
  85. package/src/models/notification.js +7 -10
  86. package/src/models/operator.js +8 -10
  87. package/src/models/organisation.js +5 -8
  88. package/src/models/send-to-api.js +18 -11
  89. package/src/models/user.js +6 -5
  90. package/src/models/utils.js +5 -8
  91. package/src/models/variables.js +18 -20
  92. package/src/parsers.js +34 -34
  93. package/src/load-package-json.cjs +0 -5
@@ -1,10 +1,14 @@
1
- import * as Application from '../models/application.js';
2
1
  import { Logger } from '../logger.js';
2
+ import * as Application from '../models/application.js';
3
3
 
4
- function validateOptions (options) {
5
-
4
+ function validateOptions(options) {
6
5
  let { flavor, 'min-flavor': minFlavor, 'max-flavor': maxFlavor } = options;
7
- let { instances, 'min-instances': minInstances, 'max-instances': maxInstances, 'build-flavor': buildFlavor } = options;
6
+ let {
7
+ instances,
8
+ 'min-instances': minInstances,
9
+ 'max-instances': maxInstances,
10
+ 'build-flavor': buildFlavor,
11
+ } = options;
8
12
 
9
13
  if ([flavor, minFlavor, maxFlavor, instances, minInstances, maxInstances, buildFlavor].every((v) => v == null)) {
10
14
  throw new Error('You should provide at least 1 option');
@@ -12,7 +16,7 @@ function validateOptions (options) {
12
16
 
13
17
  if (flavor != null) {
14
18
  if (minFlavor != null || maxFlavor != null) {
15
- throw new Error('You can\'t use --flavor and --min-flavor or --max-flavor at the same time');
19
+ throw new Error("You can't use --flavor and --min-flavor or --max-flavor at the same time");
16
20
  }
17
21
  minFlavor = flavor;
18
22
  maxFlavor = flavor;
@@ -20,38 +24,43 @@ function validateOptions (options) {
20
24
 
21
25
  if (instances != null) {
22
26
  if (minInstances != null || maxInstances != null) {
23
- throw new Error('You can\'t use --instances and --min-instances or --max-instances at the same time');
27
+ throw new Error("You can't use --instances and --min-instances or --max-instances at the same time");
24
28
  }
25
29
  minInstances = instances;
26
30
  maxInstances = instances;
27
31
  }
28
32
 
29
33
  if (minInstances != null && maxInstances != null && minInstances > maxInstances) {
30
- throw new Error('min-instances can\'t be greater than max-instances');
34
+ throw new Error("min-instances can't be greater than max-instances");
31
35
  }
32
36
 
33
37
  if (minFlavor != null && maxFlavor != null) {
34
38
  const minFlavorIndex = Application.listAvailableFlavors().indexOf(minFlavor);
35
39
  const maxFlavorIndex = Application.listAvailableFlavors().indexOf(maxFlavor);
36
40
  if (minFlavorIndex > maxFlavorIndex) {
37
- throw new Error('min-flavor can\'t be a greater flavor than max-flavor');
41
+ throw new Error("min-flavor can't be a greater flavor than max-flavor");
38
42
  }
39
43
  }
40
44
 
41
45
  return { minFlavor, maxFlavor, minInstances, maxInstances, buildFlavor };
42
46
  }
43
47
 
44
- export async function scale (params) {
48
+ export async function scale(params) {
45
49
  const { alias, app: appIdOrName } = params.options;
46
50
  const { minFlavor, maxFlavor, minInstances, maxInstances, buildFlavor } = validateOptions(params.options);
47
51
  const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
48
52
 
49
- await Application.setScalability(appId, ownerId, {
50
- minFlavor,
51
- maxFlavor,
52
- minInstances,
53
- maxInstances,
54
- }, buildFlavor);
53
+ await Application.setScalability(
54
+ appId,
55
+ ownerId,
56
+ {
57
+ minFlavor,
58
+ maxFlavor,
59
+ minInstances,
60
+ maxInstances,
61
+ },
62
+ buildFlavor,
63
+ );
55
64
 
56
65
  Logger.println('App rescaled successfully');
57
- };
66
+ }
@@ -1,9 +1,17 @@
1
+ import { styleText } from 'node:util';
2
+ import { Logger } from '../logger.js';
1
3
  import * as Addon from '../models/addon.js';
2
4
  import * as Application from '../models/application.js';
3
- import { Logger } from '../logger.js';
4
5
 
5
- export async function list (params) {
6
- const { alias, app: appIdOrName, 'show-all': showAll, 'only-apps': onlyApps, 'only-addons': onlyAddons, format } = params.options;
6
+ export async function list(params) {
7
+ const {
8
+ alias,
9
+ app: appIdOrName,
10
+ 'show-all': showAll,
11
+ 'only-apps': onlyApps,
12
+ 'only-addons': onlyAddons,
13
+ format,
14
+ } = params.options;
7
15
  if (onlyApps && onlyAddons) {
8
16
  throw new Error('--only-apps and --only-addons are mutually exclusive');
9
17
  }
@@ -38,20 +46,29 @@ export async function list (params) {
38
46
  }
39
47
  case 'human':
40
48
  default: {
41
- if (formattedServices.applications) {
49
+ const { applications = [], addons = [] } = formattedServices;
50
+
51
+ if (applications.length === 0 && addons.length === 0) {
52
+ Logger.printInfo(
53
+ `No linked services found, use ${styleText('blue', 'clever service link-app')} or ${styleText('blue', 'clever service link-addon')} to link services to an application`,
54
+ );
55
+ return;
56
+ }
57
+
58
+ if (applications.length > 0) {
42
59
  Logger.println('Applications:');
43
- formattedServices.applications.forEach(({ isLinked, name }) => Logger.println(`${isLinked ? '*' : ' '} ${name}`));
60
+ applications.forEach(({ isLinked, name }) => Logger.println(`${isLinked ? '*' : ' '} ${name}`));
44
61
  }
45
62
 
46
- if (formattedServices.addons) {
63
+ if (addons.length > 0) {
47
64
  Logger.println('Addons:');
48
- formattedServices.addons.forEach(({ isLinked, name, realId }) => Logger.println(`${isLinked ? '*' : ' '} ${name} (${realId})`));
65
+ addons.forEach(({ isLinked, name, realId }) => Logger.println(`${isLinked ? '*' : ' '} ${name} (${realId})`));
49
66
  }
50
67
  }
51
68
  }
52
69
  }
53
70
 
54
- export async function linkApp (params) {
71
+ export async function linkApp(params) {
55
72
  const { alias, app: appIdOrName } = params.options;
56
73
  const [dependency] = params.args;
57
74
  const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
@@ -60,7 +77,7 @@ export async function linkApp (params) {
60
77
  Logger.println(`App ${dependency.app_id || dependency.app_name} successfully linked`);
61
78
  }
62
79
 
63
- export async function unlinkApp (params) {
80
+ export async function unlinkApp(params) {
64
81
  const { alias, app: appIdOrName } = params.options;
65
82
  const [dependency] = params.args;
66
83
  const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
@@ -69,7 +86,7 @@ export async function unlinkApp (params) {
69
86
  Logger.println(`App ${dependency.app_id || dependency.app_name} successfully unlinked`);
70
87
  }
71
88
 
72
- export async function linkAddon (params) {
89
+ export async function linkAddon(params) {
73
90
  const { alias, app: appIdOrName } = params.options;
74
91
  const [addon] = params.args;
75
92
  const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
@@ -78,7 +95,7 @@ export async function linkAddon (params) {
78
95
  Logger.println(`Addon ${addon.addon_id || addon.addon_name} successfully linked`);
79
96
  }
80
97
 
81
- export async function unlinkAddon (params) {
98
+ export async function unlinkAddon(params) {
82
99
  const { alias, app: appIdOrName } = params.options;
83
100
  const [addon] = params.args;
84
101
  const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
@@ -1,22 +1,22 @@
1
- import { confirm } from '../lib/prompts.js';
2
- import colors from 'colors/safe.js';
3
- import { Logger } from '../logger.js';
4
- import fs from 'node:fs';
5
- import { sendToApi } from '../models/send-to-api.js';
6
- import { openBrowser } from '../models/utils.js';
7
- import dedent from 'dedent';
8
1
  import {
9
2
  todo_addSshKey as addSshKey,
10
3
  todo_getSshKeys as getSshKeys,
11
4
  todo_removeSshKey as removeSshKey,
12
5
  } from '@clevercloud/client/esm/api/v2/user.js';
6
+ import dedent from 'dedent';
7
+ import fs from 'node:fs';
8
+ import { styleText } from 'node:util';
9
+ import { confirm } from '../lib/prompts.js';
10
+ import { Logger } from '../logger.js';
11
+ import { sendToApi } from '../models/send-to-api.js';
12
+ import { openBrowser } from '../models/utils.js';
13
13
 
14
14
  /**
15
15
  * List SSH keys of the current user
16
16
  * @param {object} params The command parameters
17
17
  * @param {string} params.options.format The output format
18
18
  */
19
- export async function list (params) {
19
+ export async function list(params) {
20
20
  const { format } = params.options;
21
21
 
22
22
  const keys = await getUserSshKeys();
@@ -30,23 +30,23 @@ export async function list (params) {
30
30
  default: {
31
31
  if (keys.length === 0) {
32
32
  Logger.println(dedent`
33
- ${colors.blue('🔐 No SSH keys')}
33
+ ${styleText('blue', '🔐 No SSH keys')}
34
34
 
35
35
  To list the SSH keys on your local system, use the following command:
36
- ${colors.grey('ssh-add -l -E sha256')}
36
+ ${styleText('grey', 'ssh-add -l -E sha256')}
37
37
 
38
38
  To create a new key pair, use the following command:
39
- ${colors.grey('ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_clever -C "An optional comment"')}
39
+ ${styleText('grey', 'ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_clever -C "An optional comment"')}
40
40
 
41
41
  Then add the public key to your Clever Cloud account:
42
- ${colors.grey('clever ssh-keys add myNewKey ~/.ssh/id_ed25519_clever.pub')}
42
+ ${styleText('grey', 'clever ssh-keys add myNewKey ~/.ssh/id_ed25519_clever.pub')}
43
43
  `);
44
44
  return;
45
45
  }
46
46
 
47
47
  Logger.println(`🔐 ${keys.length} SSH key(s):`);
48
48
  keys.forEach((key) => {
49
- Logger.println(` • ${colors.blue(key.name)}`, colors.grey(`(${key.fingerprint})`));
49
+ Logger.println(` • ${styleText('blue', key.name)}`, styleText('grey', `(${key.fingerprint})`));
50
50
  });
51
51
  }
52
52
  }
@@ -57,7 +57,7 @@ export async function list (params) {
57
57
  * @param {object} params The command parameters
58
58
  * @param {Array<string>} params.args
59
59
  */
60
- export async function add (params) {
60
+ export async function add(params) {
61
61
  const [keyName, filePath] = params.args;
62
62
 
63
63
  if (!fs.existsSync(filePath)) {
@@ -69,11 +69,10 @@ export async function add (params) {
69
69
 
70
70
  try {
71
71
  await addSshKey({ key: encodeURIComponent(keyName) }, JSON.stringify(pubKeyContent)).then(sendToApi);
72
- }
73
- catch (e) {
72
+ } catch (e) {
74
73
  console.log(e?.responseBody?.id);
75
74
  if (e?.responseBody?.id === 505) {
76
- throw new Error('This SSH key is not valid, please make sure you\'re pointing to the public key file');
75
+ throw new Error("This SSH key is not valid, please make sure you're pointing to the public key file");
77
76
  }
78
77
  }
79
78
 
@@ -85,13 +84,13 @@ export async function add (params) {
85
84
  * @param {object} params The command parameters
86
85
  * @param {Array<string>} params.args
87
86
  */
88
- export async function remove (params) {
87
+ export async function remove(params) {
89
88
  const [keyName] = params.args;
90
89
 
91
90
  const keys = await getUserSshKeys();
92
91
 
93
92
  if (keys.find((key) => key.name === keyName) == null) {
94
- throw new Error(`SSH key ${colors.red(keyName)} not found`);
93
+ throw new Error(`SSH key ${styleText('red', keyName)} not found`);
95
94
  }
96
95
 
97
96
  const keyNameEncoded = encodeURIComponent(keyName);
@@ -106,12 +105,9 @@ export async function remove (params) {
106
105
  * @param {object} params.options The command options
107
106
  * @param {boolean} params.options.yes The user confirmation
108
107
  */
109
- export async function removeAll (params) {
108
+ export async function removeAll(params) {
110
109
  if (!params.options.yes) {
111
- await confirm(
112
- 'Are you sure you want to remove all your SSH keys?',
113
- 'No SSH keys removed',
114
- );
110
+ await confirm('Are you sure you want to remove all your SSH keys?', 'No SSH keys removed');
115
111
  }
116
112
 
117
113
  const keys = await getUserSshKeys();
@@ -124,7 +120,8 @@ export async function removeAll (params) {
124
120
  const results = await Promise.all(
125
121
  keys.map((key) => {
126
122
  const keyNameEncoded = encodeURIComponent(key.name);
127
- return removeSshKey({ key: keyNameEncoded }).then(sendToApi)
123
+ return removeSshKey({ key: keyNameEncoded })
124
+ .then(sendToApi)
128
125
  .then(() => [true, key.name])
129
126
  .catch(() => [false, key.name]);
130
127
  }),
@@ -132,8 +129,7 @@ export async function removeAll (params) {
132
129
 
133
130
  if (results.every(([isRemoved]) => isRemoved)) {
134
131
  Logger.printSuccess('All SSH keys were removed successfully');
135
- }
136
- else {
132
+ } else {
137
133
  const keyNamesWithErrors = results
138
134
  .filter(([isRemoved]) => !isRemoved)
139
135
  .map(([_, keyName]) => keyName)
@@ -146,14 +142,14 @@ export async function removeAll (params) {
146
142
  * Open the SSH keys management page of the Console in your browser
147
143
  * @returns {Promise<void>} A promise that resolves when the page is opened
148
144
  */
149
- export function openConsole () {
145
+ export function openConsole() {
150
146
  return openBrowser('/users/me/ssh-keys', 'Opening the SSH keys management page of the Console in your browser');
151
147
  }
152
148
 
153
149
  /**
154
150
  * @return {Promise<Array<{ name: string, key: string, fingerprint: string }>>}
155
151
  */
156
- async function getUserSshKeys () {
152
+ async function getUserSshKeys() {
157
153
  const rawKeys = await getSshKeys().then(sendToApi);
158
154
  return rawKeys.sort((a, b) => a.name.localeCompare(b.name));
159
155
  }
@@ -1,9 +1,8 @@
1
1
  import { spawn } from 'node:child_process';
2
-
3
2
  import * as Application from '../models/application.js';
4
3
  import { conf } from '../models/configuration.js';
5
4
 
6
- export async function ssh (params) {
5
+ export async function ssh(params) {
7
6
  const { alias, app: appIdOrName, 'identity-file': identityFile } = params.options;
8
7
 
9
8
  const { appId } = await Application.resolveId(appIdOrName, alias);
@@ -1,13 +1,11 @@
1
+ import { getAllInstances, get as getApplication } from '@clevercloud/client/esm/api/v2/application.js';
1
2
  import _ from 'lodash';
2
- import colors from 'colors/safe.js';
3
-
4
- import * as Application from '../models/application.js';
3
+ import { styleText } from 'node:util';
5
4
  import { Logger } from '../logger.js';
6
-
7
- import { get as getApplication, getAllInstances } from '@clevercloud/client/esm/api/v2/application.js';
5
+ import * as Application from '../models/application.js';
8
6
  import { sendToApi } from '../models/send-to-api.js';
9
7
 
10
- export async function status (params) {
8
+ export async function status(params) {
11
9
  const { alias, app: appIdOrName, format } = params.options;
12
10
  const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
13
11
 
@@ -23,30 +21,37 @@ export async function status (params) {
23
21
  }
24
22
  case 'human':
25
23
  default: {
26
- const statusMessage = status.status === 'running'
27
- ? `${colors.bold.green('running')} ${displayInstances(status.instances, status.commit)}`
28
- : colors.bold.red('stopped');
24
+ const statusMessage =
25
+ status.status === 'running'
26
+ ? `${styleText(['bold', 'green'], 'running')} ${displayInstances(status.instances, status.commit)}`
27
+ : styleText(['bold', 'red'], 'stopped');
29
28
 
30
29
  Logger.println(`${status.name}: ${statusMessage}`);
31
- Logger.println(`Executed as: ${colors.bold(status.lifetime)}`);
30
+ Logger.println(`Executed as: ${styleText('bold', status.lifetime)}`);
32
31
  if (status.deploymentInProgress) {
33
- Logger.println(`Deployment in progress ${displayInstances(status.deploymentInProgress.instances, status.deploymentInProgress.commit)}`);
32
+ Logger.println(
33
+ `Deployment in progress ${displayInstances(status.deploymentInProgress.instances, status.deploymentInProgress.commit)}`,
34
+ );
34
35
  }
35
36
  Logger.println();
36
37
  Logger.println('Scalability:');
37
- Logger.println(` Auto scalability: ${status.scalability.enabled ? colors.green('enabled') : colors.red('disabled')}`);
38
- Logger.println(` Scalers: ${colors.bold(formatScalability(status.scalability.horizontal))}`);
39
- Logger.println(` Sizes: ${colors.bold(formatScalability(status.scalability.vertical))}`);
40
- Logger.println(` Dedicated build: ${status.separateBuild ? colors.bold(status.buildFlavor) : colors.red('disabled')}`);
38
+ Logger.println(
39
+ ` Auto scalability: ${status.scalability.enabled ? styleText('green', 'enabled') : styleText('red', 'disabled')}`,
40
+ );
41
+ Logger.println(` Scalers: ${styleText('bold', formatScalability(status.scalability.horizontal))}`);
42
+ Logger.println(` Sizes: ${styleText('bold', formatScalability(status.scalability.vertical))}`);
43
+ Logger.println(
44
+ ` Dedicated build: ${status.separateBuild ? styleText('bold', status.buildFlavor) : styleText('red', 'disabled')}`,
45
+ );
41
46
  }
42
47
  }
43
48
  }
44
49
 
45
- function displayInstances (instances, commit) {
50
+ function displayInstances(instances, commit) {
46
51
  return `(${instances.map((instance) => `${instance.count}*${instance.flavor}`)}, Commit: ${commit || 'N/A'})`;
47
52
  }
48
53
 
49
- function computeStatus (instances, app) {
54
+ function computeStatus(instances, app) {
50
55
  const upInstances = _.filter(instances, ({ state }) => state === 'UP');
51
56
  const isUp = !_.isEmpty(upInstances);
52
57
  const upCommit = _(upInstances).map('commit').head();
@@ -57,8 +62,7 @@ function computeStatus (instances, app) {
57
62
 
58
63
  const { minFlavor, maxFlavor, minInstances, maxInstances } = app.instance;
59
64
 
60
- const scalabilityEnabled = (minFlavor.name !== maxFlavor.name)
61
- || (minInstances !== maxInstances);
65
+ const scalabilityEnabled = minFlavor.name !== maxFlavor.name || minInstances !== maxInstances;
62
66
 
63
67
  const status = {
64
68
  id: app.id,
@@ -86,11 +90,16 @@ function computeStatus (instances, app) {
86
90
  return status;
87
91
  }
88
92
 
89
- function formatScalability ({ min, max }) {
90
- return (min === max) ? min : `${min} to ${max}`;
93
+ /**
94
+ * @param {number} min
95
+ * @param {number} max
96
+ * @returns {string}
97
+ */
98
+ function formatScalability({ min, max }) {
99
+ return min === max ? min.toString() : `${min} to ${max}`;
91
100
  }
92
101
 
93
- function groupInstances (instances) {
102
+ function groupInstances(instances) {
94
103
  return _(instances)
95
104
  .groupBy((i) => i.flavor.name)
96
105
  .map((instances, flavorName) => ({
@@ -1,9 +1,9 @@
1
- import * as Application from '../models/application.js';
1
+ import { undeploy as stopApplication } from '@clevercloud/client/esm/api/v2/application.js';
2
2
  import { Logger } from '../logger.js';
3
+ import * as Application from '../models/application.js';
3
4
  import { sendToApi } from '../models/send-to-api.js';
4
- import { undeploy as stopApplication } from '@clevercloud/client/esm/api/v2/application.js';
5
5
 
6
- export async function stop (params) {
6
+ export async function stop(params) {
7
7
  const { alias, app: appIdOrName } = params.options;
8
8
  const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
9
9
 
@@ -1,13 +1,12 @@
1
- import colors from 'colors/safe.js';
2
-
3
- import * as Namespaces from '../models/namespaces.js';
4
- import { sendToApi } from '../models/send-to-api.js';
1
+ import { addTcpRedir, getTcpRedirs, removeTcpRedir } from '@clevercloud/client/esm/api/v2/application.js';
2
+ import { styleText } from 'node:util';
5
3
  import { confirm } from '../lib/prompts.js';
6
4
  import { Logger } from '../logger.js';
7
5
  import * as Application from '../models/application.js';
8
- import { addTcpRedir, getTcpRedirs, removeTcpRedir } from '@clevercloud/client/esm/api/v2/application.js';
6
+ import * as Namespaces from '../models/namespaces.js';
7
+ import { sendToApi } from '../models/send-to-api.js';
9
8
 
10
- export async function listNamespaces (params) {
9
+ export async function listNamespaces(params) {
11
10
  const { alias, app: appIdOrName, format } = params.options;
12
11
  const { ownerId } = await Application.resolveId(appIdOrName, alias);
13
12
 
@@ -40,7 +39,7 @@ export async function listNamespaces (params) {
40
39
  }
41
40
  }
42
41
 
43
- export async function list (params) {
42
+ export async function list(params) {
44
43
  const { alias, app: appIdOrName, format } = params.options;
45
44
  const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
46
45
 
@@ -55,8 +54,7 @@ export async function list (params) {
55
54
  default: {
56
55
  if (redirs.length === 0) {
57
56
  Logger.println('No active TCP redirection for this application');
58
- }
59
- else {
57
+ } else {
60
58
  Logger.println('Enabled TCP redirections:');
61
59
  for (const { namespace, port } of redirs) {
62
60
  Logger.println(port + ' on ' + namespace);
@@ -66,11 +64,13 @@ export async function list (params) {
66
64
  }
67
65
  }
68
66
 
69
- async function acceptPayment (result, skipConfirmation) {
67
+ async function acceptPayment(result, skipConfirmation) {
70
68
  if (!skipConfirmation) {
71
- result.lines.forEach(({ description, VAT, price }) => Logger.println(`${description}\tVAT: ${VAT}%\tPrice: ${price}€`));
69
+ result.lines.forEach(({ description, VAT, price }) =>
70
+ Logger.println(`${description}\tVAT: ${VAT}%\tPrice: ${price}€`),
71
+ );
72
72
  Logger.println(`Total (without taxes): ${result.totalHT}€`);
73
- Logger.println(colors.bold(`Total (with taxes): ${result.totalTTC}€`));
73
+ Logger.println(styleText('bold', `Total (with taxes): ${result.totalTTC}€`));
74
74
 
75
75
  await confirm(
76
76
  `You're about to pay ${result.totalTTC}€, confirm?`,
@@ -79,25 +79,26 @@ async function acceptPayment (result, skipConfirmation) {
79
79
  }
80
80
  }
81
81
 
82
- export async function add (params) {
82
+ export async function add(params) {
83
83
  const { alias, app: appIdOrName, namespace, yes: skipConfirmation } = params.options;
84
84
  const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
85
85
 
86
- const { port } = await addTcpRedir({ id: ownerId, appId }, { namespace }).then(sendToApi).catch((error) => {
87
- if (error.status === 402) {
88
- return acceptPayment(error.response.body, skipConfirmation).then(() => {
89
- return addTcpRedir({ id: ownerId, appId, payment: 'accepted' }, { namespace }).then(sendToApi);
90
- });
91
- }
92
- else {
93
- throw error;
94
- }
95
- });
86
+ const { port } = await addTcpRedir({ id: ownerId, appId }, { namespace })
87
+ .then(sendToApi)
88
+ .catch((error) => {
89
+ if (error.status === 402) {
90
+ return acceptPayment(error.response.body, skipConfirmation).then(() => {
91
+ return addTcpRedir({ id: ownerId, appId, payment: 'accepted' }, { namespace }).then(sendToApi);
92
+ });
93
+ } else {
94
+ throw error;
95
+ }
96
+ });
96
97
 
97
98
  Logger.println('Successfully added tcp redirection on port: ' + port);
98
- };
99
+ }
99
100
 
100
- export async function remove (params) {
101
+ export async function remove(params) {
101
102
  const [port] = params.args;
102
103
  const { alias, app: appIdOrName, namespace } = params.options;
103
104
  const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
@@ -105,4 +106,4 @@ export async function remove (params) {
105
106
  await removeTcpRedir({ id: ownerId, appId, sourcePort: port, namespace }).then(sendToApi);
106
107
 
107
108
  Logger.println('Successfully removed tcp redirection.');
108
- };
109
+ }