clever-tools 3.14.0 → 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 +61 -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 +32 -31
  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 +18 -9
  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 +24 -22
  64. package/src/models/activity.js +3 -3
  65. package/src/models/addon.js +52 -53
  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,21 +1,21 @@
1
- import colors from 'colors/safe.js';
2
- import * as User from '../models/user.js';
3
- import { Logger } from '../logger.js';
4
- import { openBrowser } from '../models/utils.js';
5
- import { sendToApi } from '../models/send-to-api.js';
6
- import { confirm } from '../lib/prompts.js';
7
1
  import {
8
2
  todo_addEmailAddress as addEmailAddress,
9
3
  todo_getEmailAddresses as getEmailAddresses,
10
4
  todo_removeEmailAddress as removeEmailAddress,
11
5
  } from '@clevercloud/client/esm/api/v2/user.js';
6
+ import { styleText } from 'node:util';
7
+ import { confirm } from '../lib/prompts.js';
8
+ import { Logger } from '../logger.js';
9
+ import { sendToApi } from '../models/send-to-api.js';
10
+ import * as User from '../models/user.js';
11
+ import { openBrowser } from '../models/utils.js';
12
12
 
13
13
  /**
14
14
  * Show primary and secondary email addresses of the current user
15
15
  * @param {object} params The command parameters
16
16
  * @param {string} params.options.format The output format
17
17
  */
18
- export async function list (params) {
18
+ export async function list(params) {
19
19
  const { format } = params.options;
20
20
  const addresses = await getUserEmailAddresses();
21
21
 
@@ -27,13 +27,11 @@ export async function list (params) {
27
27
  case 'human':
28
28
  default: {
29
29
  Logger.println('✉️ Primary email address:');
30
- Logger.println(` • ${colors.green(addresses.primary)}`);
30
+ Logger.println(` • ${styleText('green', addresses.primary)}`);
31
31
  if (addresses.secondary.length > 0) {
32
32
  Logger.println();
33
33
  Logger.println(`✉️ ${addresses.secondary.length} secondary email address(es):`);
34
- addresses.secondary.forEach((address) =>
35
- Logger.println(` • ${colors.blue(address)}`),
36
- );
34
+ addresses.secondary.forEach((address) => Logger.println(` • ${styleText('blue', address)}`));
37
35
  }
38
36
  }
39
37
  }
@@ -44,15 +42,16 @@ export async function list (params) {
44
42
  * @param {object} params The command parameters
45
43
  * @param {Array<string>} params.args
46
44
  */
47
- export async function addSecondary (params) {
45
+ export async function addSecondary(params) {
48
46
  const [secondaryAddress] = params.args;
49
47
 
50
48
  const secondaryAddressEncoded = encodeURIComponent(secondaryAddress);
51
49
  try {
52
50
  await addEmailAddress({ email: secondaryAddressEncoded }).then(sendToApi);
53
- Logger.printSuccess(`The server sent a confirmation email to ${secondaryAddress} to validate your secondary address`);
54
- }
55
- catch (e) {
51
+ Logger.printSuccess(
52
+ `The server sent a confirmation email to ${secondaryAddress} to validate your secondary address`,
53
+ );
54
+ } catch (e) {
56
55
  switch (e?.responseBody?.id) {
57
56
  case 101:
58
57
  throw new Error('This address already belongs to your account');
@@ -71,7 +70,7 @@ export async function addSecondary (params) {
71
70
  * @param {object} params The command parameters
72
71
  * @param {Array<string>} params.args
73
72
  */
74
- export async function setPrimary (params) {
73
+ export async function setPrimary(params) {
75
74
  const [newPrimaryAddress] = params.args;
76
75
 
77
76
  const addresses = await getUserEmailAddresses();
@@ -95,13 +94,13 @@ export async function setPrimary (params) {
95
94
  * @param {object} params The command parameters
96
95
  * @param {Array<string>} params.args
97
96
  */
98
- export async function removeSecondary (params) {
97
+ export async function removeSecondary(params) {
99
98
  const [addressToRemove] = params.args;
100
99
 
101
100
  const addresses = await getUserEmailAddresses();
102
101
 
103
102
  if (!addresses.secondary.includes(addressToRemove)) {
104
- throw new Error('This address is not part of the secondary addresses of the current user, it can\'t be removed');
103
+ throw new Error("This address is not part of the secondary addresses of the current user, it can't be removed");
105
104
  }
106
105
 
107
106
  const addressToRemoveEncoded = encodeURIComponent(addressToRemove);
@@ -116,12 +115,9 @@ export async function removeSecondary (params) {
116
115
  * @param {object} params.options The command options
117
116
  * @param {boolean} params.options.yes The user confirmation
118
117
  */
119
- export async function removeAllSecondary (params) {
118
+ export async function removeAllSecondary(params) {
120
119
  if (!params.options.yes) {
121
- await confirm(
122
- 'Are you sure you want to remove all your secondary addresses?',
123
- 'No secondary addresses removed',
124
- );
120
+ await confirm('Are you sure you want to remove all your secondary addresses?', 'No secondary addresses removed');
125
121
  }
126
122
 
127
123
  const addresses = await getUserEmailAddresses();
@@ -134,7 +130,8 @@ export async function removeAllSecondary (params) {
134
130
  const results = await Promise.all(
135
131
  addresses.secondary.map((addressToRemove) => {
136
132
  const addressToRemoveEncoded = encodeURIComponent(addressToRemove);
137
- return removeEmailAddress({ email: addressToRemoveEncoded }).then(sendToApi)
133
+ return removeEmailAddress({ email: addressToRemoveEncoded })
134
+ .then(sendToApi)
138
135
  .then(() => [true, addressToRemove])
139
136
  .catch(() => [false, addressToRemove]);
140
137
  }),
@@ -142,8 +139,7 @@ export async function removeAllSecondary (params) {
142
139
 
143
140
  if (results.every(([isRemoved]) => isRemoved)) {
144
141
  Logger.printSuccess('All secondary addresses were removed successfully');
145
- }
146
- else {
142
+ } else {
147
143
  const addressesWithErrors = results
148
144
  .filter(([isRemoved]) => !isRemoved)
149
145
  .map(([_, address]) => address)
@@ -156,7 +152,7 @@ export async function removeAllSecondary (params) {
156
152
  * Open the email addresses management page of the Console in your browser
157
153
  * @returns {Promise<void>} A promise that resolves when the page is opened
158
154
  */
159
- export function openConsole () {
155
+ export function openConsole() {
160
156
  return openBrowser('/users/me/emails', 'Opening the email addresses management page of the Console in your browser');
161
157
  }
162
158
 
@@ -164,7 +160,7 @@ export function openConsole () {
164
160
  * Get the primary and secondary email addresses of the current user
165
161
  * @returns {Promise<{ primary: string, secondary: string[] }>} The primary and secondary email addresses of the current user
166
162
  */
167
- async function getUserEmailAddresses () {
163
+ async function getUserEmailAddresses() {
168
164
  const currentUser = await User.getCurrent();
169
165
  const secondaryAddresses = await getEmailAddresses().then(sendToApi);
170
166
  return {
@@ -1,19 +1,19 @@
1
- import * as Application from '../models/application.js';
2
- import { Logger } from '../logger.js';
3
- import colors from 'colors/safe.js';
4
- import * as variables from '../models/variables.js';
5
- import { sendToApi } from '../models/send-to-api.js';
6
- import { toNameEqualsValueString, validateName } from '@clevercloud/client/esm/utils/env-vars.js';
7
1
  import {
8
2
  getAllEnvVars,
9
3
  getAllEnvVarsForAddons,
10
4
  getAllEnvVarsForDependencies,
11
- updateEnvVar,
12
- updateAllEnvVars,
13
5
  removeEnvVar,
6
+ updateAllEnvVars,
7
+ updateEnvVar,
14
8
  } from '@clevercloud/client/esm/api/v2/application.js';
9
+ import { toNameEqualsValueString, validateName } from '@clevercloud/client/esm/utils/env-vars.js';
10
+ import { styleText } from 'node:util';
11
+ import { Logger } from '../logger.js';
12
+ import * as Application from '../models/application.js';
13
+ import { sendToApi } from '../models/send-to-api.js';
14
+ import * as variables from '../models/variables.js';
15
15
 
16
- export async function list (params) {
16
+ export async function list(params) {
17
17
  const { alias, app: appIdOrName, 'add-export': addExportsOption, format } = params.options;
18
18
  const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
19
19
 
@@ -44,7 +44,7 @@ export async function list (params) {
44
44
  case 'human':
45
45
  default: {
46
46
  if (addExportsOption) {
47
- Logger.println(colors.yellow('`--add-export` option is deprecated. Use `--format shell` instead.'));
47
+ Logger.println(styleText('yellow', '`--add-export` option is deprecated. Use `--format shell` instead.'));
48
48
  }
49
49
 
50
50
  const addExports = addExportsOption || format === 'shell';
@@ -65,7 +65,7 @@ export async function list (params) {
65
65
  }
66
66
  }
67
67
 
68
- export async function set (params) {
68
+ export async function set(params) {
69
69
  const [envName, value] = params.args;
70
70
  const { alias, app: appIdOrName } = params.options;
71
71
 
@@ -79,9 +79,9 @@ export async function set (params) {
79
79
  await updateEnvVar({ id: ownerId, appId, envName }, { value }).then(sendToApi);
80
80
 
81
81
  Logger.println('Your environment variable has been successfully saved');
82
- };
82
+ }
83
83
 
84
- export async function rm (params) {
84
+ export async function rm(params) {
85
85
  const [envName] = params.args;
86
86
  const { alias, app: appIdOrName } = params.options;
87
87
  const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
@@ -89,9 +89,9 @@ export async function rm (params) {
89
89
  await removeEnvVar({ id: ownerId, appId, envName }).then(sendToApi);
90
90
 
91
91
  Logger.println('Your environment variable has been successfully removed');
92
- };
92
+ }
93
93
 
94
- export async function importEnv (params) {
94
+ export async function importEnv(params) {
95
95
  const { alias, app: appIdOrName, json } = params.options;
96
96
  const format = json ? 'json' : 'name-equals-value';
97
97
  const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
@@ -100,9 +100,9 @@ export async function importEnv (params) {
100
100
  await updateAllEnvVars({ id: ownerId, appId }, envVars).then(sendToApi);
101
101
 
102
102
  Logger.println('Environment variables have been set');
103
- };
103
+ }
104
104
 
105
- export async function importVarsFromLocalEnv (params) {
105
+ export async function importVarsFromLocalEnv(params) {
106
106
  const [envNames] = params.args;
107
107
  const { alias, app: appIdOrName } = params.options;
108
108
 
@@ -121,4 +121,4 @@ export async function importVarsFromLocalEnv (params) {
121
121
  }
122
122
 
123
123
  Logger.println('Your environment variables have been successfully saved');
124
- };
124
+ }
@@ -1,11 +1,9 @@
1
- import { getFeatures, setFeature } from '../models/configuration.js';
2
1
  import { EXPERIMENTAL_FEATURES } from '../experimental-features.js';
3
- import { formatTable as initFormatTable } from '../format-table.js';
2
+ import { formatTable } from '../format-table.js';
4
3
  import { Logger } from '../logger.js';
4
+ import { getFeatures, setFeature } from '../models/configuration.js';
5
5
 
6
- const formatTable = initFormatTable();
7
-
8
- export async function list (params) {
6
+ export async function list(params) {
9
7
  const { format } = params.options;
10
8
 
11
9
  const featuresConf = await getFeatures();
@@ -30,20 +28,17 @@ export async function list (params) {
30
28
  default: {
31
29
  const headers = ['ID', 'STATUS', 'DESCRIPTION', 'ENABLED'];
32
30
 
33
- Logger.println(formatTable([
34
- headers,
35
- ...features.map((feature) => [
36
- feature.id,
37
- feature.status,
38
- feature.description,
39
- feature.enabled,
31
+ Logger.println(
32
+ formatTable([
33
+ headers,
34
+ ...features.map((feature) => [feature.id, feature.status, feature.description, feature.enabled]),
40
35
  ]),
41
- ]));
36
+ );
42
37
  }
43
38
  }
44
39
  }
45
40
 
46
- export async function info (params) {
41
+ export async function info(params) {
47
42
  const { feature } = params.namedArgs;
48
43
  const availableFeatures = Object.keys(EXPERIMENTAL_FEATURES);
49
44
 
@@ -54,7 +49,7 @@ export async function info (params) {
54
49
  Logger.println(EXPERIMENTAL_FEATURES[feature].instructions);
55
50
  }
56
51
 
57
- export async function enable (params) {
52
+ export async function enable(params) {
58
53
  const { features } = params.namedArgs;
59
54
  const availableFeatures = Object.keys(EXPERIMENTAL_FEATURES);
60
55
 
@@ -70,14 +65,13 @@ export async function enable (params) {
70
65
 
71
66
  if (features.length === 1) {
72
67
  Logger.println(EXPERIMENTAL_FEATURES[features[0]].instructions);
73
- }
74
- else {
68
+ } else {
75
69
  Logger.println();
76
70
  Logger.println("To learn more about these experimental features, use 'clever features info FEATURE_NAME'");
77
71
  }
78
72
  }
79
73
 
80
- export async function disable (params) {
74
+ export async function disable(params) {
81
75
  const { features } = params.namedArgs;
82
76
  const availableFeatures = Object.keys(EXPERIMENTAL_FEATURES);
83
77
 
@@ -19,7 +19,7 @@ import {
19
19
  * @param {string} params.options.format The output format
20
20
  * @returns {Promise<void>}
21
21
  */
22
- export async function checkVersion (params) {
22
+ export async function checkVersion(params) {
23
23
  const [addonIdOrName] = params.args;
24
24
  const { format } = params.options;
25
25
  await operatorCheckVersion('keycloak', addonIdOrName, format);
@@ -31,7 +31,7 @@ export async function checkVersion (params) {
31
31
  * @param {string} params.args[0] The operator's name or ID
32
32
  * @returns {Promise<void>}
33
33
  */
34
- export async function updateVersion (params) {
34
+ export async function updateVersion(params) {
35
35
  const [addonIdOrName] = params.args;
36
36
  const { target } = params.options;
37
37
  await operatorUpdateVersion('keycloak', target, addonIdOrName);
@@ -44,7 +44,7 @@ export async function updateVersion (params) {
44
44
  * @param {string} params.options.format The output format
45
45
  * @returns {Promise<void>}
46
46
  */
47
- export async function get (params) {
47
+ export async function get(params) {
48
48
  const [addonIdOrName] = params.args;
49
49
  const { format } = params.options;
50
50
  await operatorPrint('keycloak', addonIdOrName, format);
@@ -54,7 +54,7 @@ export async function get (params) {
54
54
  * List all Keycloak operators
55
55
  * @returns {Promise<void>}
56
56
  */
57
- export async function list (params) {
57
+ export async function list(params) {
58
58
  await operatorList('keycloak', params.options.format);
59
59
  }
60
60
 
@@ -65,7 +65,7 @@ export async function list (params) {
65
65
  * @returns {Promise<void>}
66
66
  * @throws {Error} If the Network Group feature is already disabled
67
67
  */
68
- export async function ngDisable (params) {
68
+ export async function ngDisable(params) {
69
69
  const [addonIdOrName] = params.args;
70
70
  await operatorNgDisable('keycloak', addonIdOrName);
71
71
  }
@@ -77,7 +77,7 @@ export async function ngDisable (params) {
77
77
  * @returns {Promise<void>}
78
78
  * @throws {Error} If the Network Group feature is already enabled
79
79
  */
80
- export async function ngEnable (params) {
80
+ export async function ngEnable(params) {
81
81
  const [addonIdOrName] = params.args;
82
82
  await operatorNgEnable('keycloak', addonIdOrName);
83
83
  }
@@ -88,7 +88,7 @@ export async function ngEnable (params) {
88
88
  * @param {string} params.args[0] The operator's name or ID
89
89
  * @returns {Promise<void>}
90
90
  */
91
- export async function open (params) {
91
+ export async function open(params) {
92
92
  const [addonIdOrName] = params.args;
93
93
  await operatorOpen('keycloak', addonIdOrName);
94
94
  }
@@ -99,7 +99,7 @@ export async function open (params) {
99
99
  * @param {string} params.args[0] The operator's name or ID
100
100
  * @returns {Promise<void>}
101
101
  */
102
- export async function openLogs (params) {
102
+ export async function openLogs(params) {
103
103
  const [addonIdOrName] = params.args;
104
104
  await operatorOpenLogs('keycloak', addonIdOrName);
105
105
  }
@@ -110,7 +110,7 @@ export async function openLogs (params) {
110
110
  * @param {string} params.args[0] The operator's name or ID
111
111
  * @returns {Promise<void>}
112
112
  */
113
- export async function openWebUi (params) {
113
+ export async function openWebUi(params) {
114
114
  const [addonIdOrName] = params.args;
115
115
  await operatorOpenWebUi('keycloak', addonIdOrName);
116
116
  }
@@ -121,7 +121,7 @@ export async function openWebUi (params) {
121
121
  * @param {string} params.args[0] The operator's name or ID
122
122
  * @returns {Promise<void>}
123
123
  */
124
- export async function reboot (params) {
124
+ export async function reboot(params) {
125
125
  const [addonIdOrName] = params.args;
126
126
  await operatorReboot('keycloak', addonIdOrName);
127
127
  }
@@ -132,7 +132,7 @@ export async function reboot (params) {
132
132
  * @param {string} params.args[0] The operator's name or ID
133
133
  * @returns {Promise<void>}
134
134
  */
135
- export async function rebuild (params) {
135
+ export async function rebuild(params) {
136
136
  const [addonIdOrName] = params.args;
137
137
  await operatorRebuild('keycloak', addonIdOrName);
138
138
  }
@@ -1,9 +1,9 @@
1
+ import { getAllEnvVars } from '@clevercloud/client/esm/api/v2/addon.js';
1
2
  import Redis from 'ioredis';
2
- import colors from 'colors/safe.js';
3
+ import { styleText } from 'node:util';
3
4
  import { Logger } from '../logger.js';
4
- import { sendToApi } from '../models/send-to-api.js';
5
- import { getAllEnvVars } from '@clevercloud/client/esm/api/v2/addon.js';
6
5
  import { findAddonsByNameOrId } from '../models/ids-resolver.js';
6
+ import { sendToApi } from '../models/send-to-api.js';
7
7
 
8
8
  const URL_ENV_KEY = 'REDIS_URL';
9
9
  const MAX_RETRIES_PER_REQUEST = 1;
@@ -16,7 +16,7 @@ const MAX_RETRIES_PER_REQUEST = 1;
16
16
  * @param {string} params.options.format
17
17
  * @returns {Promise<void>}
18
18
  */
19
- export async function sendRawCommand (params) {
19
+ export async function sendRawCommand(params) {
20
20
  const [addonIdOrRealIdOrName] = params.args;
21
21
  const { org, format } = params.options;
22
22
 
@@ -28,7 +28,7 @@ export async function sendRawCommand (params) {
28
28
 
29
29
  if (addons.length > 1) {
30
30
  const formattedAddons = addons
31
- .map(({ addonId, ownerId }) => `\n${colors.grey(`- ${addonId} (${ownerId})`)}`)
31
+ .map(({ addonId, ownerId }) => `\n${styleText('grey', `- ${addonId} (${ownerId})`)}`)
32
32
  .join('');
33
33
  throw new Error(`Several add-ons found for '${addonIdOrRealIdOrName}', use ID instead:${formattedAddons}`);
34
34
  }
@@ -56,17 +56,18 @@ export async function sendRawCommand (params) {
56
56
 
57
57
  /**
58
58
  * Get the URL of the compatible KV database
59
- * @param {string} ownerId
60
- * @param {string} addonId
59
+ * @param {string} ownerId
60
+ * @param {string} addonId
61
61
  * @returns {Promise<string>} the URL of the compatible KV database
62
62
  */
63
- async function getAddonUrl (ownerId, addonId) {
64
-
63
+ async function getAddonUrl(ownerId, addonId) {
65
64
  const envVars = await getAllEnvVars({ id: ownerId, addonId }).then(sendToApi);
66
65
  const redisUrl = envVars.find((env) => env.name === URL_ENV_KEY)?.value;
67
66
 
68
67
  if (!redisUrl) {
69
- throw new Error(`Environment variable ${colors.red(URL_ENV_KEY)} not found, is it a Materia KV or Redis® add-on?`);
68
+ throw new Error(
69
+ `Environment variable ${styleText('red', URL_ENV_KEY)} not found, is it a Materia KV or Redis® add-on?`,
70
+ );
70
71
  }
71
72
 
72
73
  return redisUrl;
@@ -78,15 +79,14 @@ async function getAddonUrl (ownerId, addonId) {
78
79
  * @param {Array<string>} command
79
80
  * @returns {Promise<string>} the command result
80
81
  */
81
- async function sendCommand (url, command) {
82
+ async function sendCommand(url, command) {
82
83
  Logger.debug(`Sending command '${command.join(' ')}' to ${url}`);
83
84
  const client = new Redis(url, { maxRetriesPerRequest: MAX_RETRIES_PER_REQUEST });
84
85
  try {
85
86
  const result = await client.call(...command);
86
87
  Logger.debug(`Command result: ${result}`);
87
88
  return result;
88
- }
89
- finally {
89
+ } finally {
90
90
  await client.disconnect();
91
91
  Logger.debug('Disconnected from server');
92
92
  }
@@ -1,19 +1,20 @@
1
- import * as Application from '../models/application.js';
1
+ import { styleText } from 'node:util';
2
2
  import { Logger } from '../logger.js';
3
- import colors from 'colors/safe.js';
3
+ import * as Application from '../models/application.js';
4
4
 
5
- export async function link (params) {
5
+ export async function link(params) {
6
6
  const [app] = params.args;
7
7
  const { org: orgaIdOrName, alias } = params.options;
8
8
 
9
9
  if (app.app_id != null && orgaIdOrName != null) {
10
- Logger.warn('You\'ve specified a unique application ID, organisation option will be ignored');
10
+ Logger.warn("You've specified a unique application ID, organisation option will be ignored");
11
11
  await Application.linkRepo(app, null, alias);
12
- }
13
- else {
12
+ } else {
14
13
  await Application.linkRepo(app, orgaIdOrName, alias);
15
14
  }
16
15
 
17
- const linkedMessage = alias ? ` to local alias ${colors.green(alias)}` : '';
18
- Logger.printSuccess(`Application ${colors.green(app.app_name || app.app_id)} has been successfully linked${linkedMessage}!`);
16
+ const linkedMessage = alias ? ` to local alias ${styleText('green', alias)}` : '';
17
+ Logger.printSuccess(
18
+ `Application ${styleText('green', app.app_name || app.app_id)} has been successfully linked${linkedMessage}!`,
19
+ );
19
20
  }
@@ -1,29 +1,21 @@
1
1
  import crypto from 'node:crypto';
2
- import util from 'node:util';
3
-
4
- import colors from 'colors/safe.js';
2
+ import { setTimeout as delay } from 'node:timers/promises';
3
+ import { styleText } from 'node:util';
5
4
  import open from 'open';
6
- import superagent from 'superagent';
7
-
5
+ import pkg from '../../package.json' with { type: 'json' };
8
6
  import { Logger } from '../logger.js';
9
- import * as User from '../models/user.js';
10
7
  import { conf, writeOAuthConf } from '../models/configuration.js';
11
-
12
- import { getPackageJson } from '../load-package-json.cjs';
13
-
14
- const delay = util.promisify(setTimeout);
15
- const pkg = getPackageJson();
8
+ import * as User from '../models/user.js';
16
9
 
17
10
  // 20 random bytes as Base64URL
18
- function randomToken () {
11
+ function randomToken() {
19
12
  return crypto.randomBytes(20).toString('base64').replace(/\//g, '-').replace(/\+/g, '_').replace(/=/g, '');
20
13
  }
21
14
 
22
15
  const POLLING_INTERVAL = 2000;
23
16
  const POLLING_MAX_TRY_COUNT = 60;
24
17
 
25
- function pollOauthData (url, tryCount = 0) {
26
-
18
+ function pollOauthData(url, tryCount = 0) {
27
19
  if (tryCount >= POLLING_MAX_TRY_COUNT) {
28
20
  throw new Error('Something went wrong while trying to log you in.');
29
21
  }
@@ -31,21 +23,21 @@ function pollOauthData (url, tryCount = 0) {
31
23
  Logger.println("We're still waiting for the login process (in your browser) to be completed…");
32
24
  }
33
25
 
34
- return superagent
35
- .get(url)
36
- .send()
37
- .then(({ body }) => body)
38
- .catch(async (e) => {
39
- if (e.status === 404) {
26
+ return globalThis
27
+ .fetch(url)
28
+ .then(async (r) => {
29
+ if (r.status === 404) {
40
30
  await delay(POLLING_INTERVAL);
41
31
  return pollOauthData(url, tryCount + 1);
42
32
  }
33
+ return r.json();
34
+ })
35
+ .catch(async () => {
43
36
  throw new Error('Something went wrong while trying to log you in.');
44
37
  });
45
38
  }
46
39
 
47
- async function loginViaConsole () {
48
-
40
+ async function loginViaConsole() {
49
41
  const cliToken = randomToken();
50
42
 
51
43
  const consoleUrl = new URL(conf.CONSOLE_TOKEN_URL);
@@ -57,16 +49,16 @@ async function loginViaConsole () {
57
49
  cliPollUrl.searchParams.set('cli_token', cliToken);
58
50
 
59
51
  Logger.debug('Try to login to Clever Cloud…');
60
- Logger.println(`Opening ${colors.green(consoleUrl.toString())} in your browser to log you in…`);
52
+ Logger.println(`Opening ${styleText('green', consoleUrl.toString())} in your browser to log you in…`);
61
53
  await open(consoleUrl.toString(), { wait: false });
62
54
 
63
55
  return pollOauthData(cliPollUrl.toString());
64
56
  }
65
57
 
66
- export async function login (params) {
58
+ export async function login(params) {
67
59
  const { token, secret } = params.options;
68
- const isLoginWithArgs = (token != null && secret != null);
69
- const isInteractiveLogin = (token == null && secret == null);
60
+ const isLoginWithArgs = token != null && secret != null;
61
+ const isInteractiveLogin = token == null && secret == null;
70
62
 
71
63
  if (isLoginWithArgs) {
72
64
  return writeOAuthConf({ token, secret });
@@ -76,7 +68,7 @@ export async function login (params) {
76
68
  const oauthData = await loginViaConsole();
77
69
  await writeOAuthConf(oauthData);
78
70
  const { name, email } = await User.getCurrent();
79
- const formattedName = name || colors.red.bold('[unspecified name]');
71
+ const formattedName = name || styleText(['red', 'bold'], '[unspecified name]');
80
72
  return Logger.println(`Login successful as ${formattedName} <${email}>`);
81
73
  }
82
74
 
@@ -1,7 +1,7 @@
1
1
  import { Logger } from '../logger.js';
2
2
  import { conf, writeOAuthConf } from '../models/configuration.js';
3
3
 
4
- export async function logout () {
4
+ export async function logout() {
5
5
  // write empty object
6
6
  await writeOAuthConf({});
7
7
  Logger.println(`${conf.CONFIGURATION_FILE} has been updated.`);
@@ -1,25 +1,33 @@
1
+ import { styleText } from 'node:util';
2
+ import { Logger } from '../logger.js';
1
3
  import * as Application from '../models/application.js';
2
- import * as LogV2 from '../models/log.js';
4
+ import { resolveAddonId } from '../models/ids-resolver.js';
3
5
  import * as Log from '../models/log-v4.js';
4
- import { Logger } from '../logger.js';
6
+ import * as LogV2 from '../models/log.js';
5
7
  import { Deferred } from '../models/utils.js';
6
- import colors from 'colors/safe.js';
7
- import { resolveAddonId } from '../models/ids-resolver.js';
8
8
 
9
- export async function appLogs (params) {
10
- const { alias, app: appIdOrName, addon: addonIdOrRealId, after: since, before: until, search, 'deployment-id': deploymentId, format } = params.options;
9
+ export async function appLogs(params) {
10
+ const {
11
+ alias,
12
+ app: appIdOrName,
13
+ addon: addonIdOrRealId,
14
+ after: since,
15
+ before: until,
16
+ search,
17
+ 'deployment-id': deploymentId,
18
+ format,
19
+ } = params.options;
11
20
 
12
21
  // ignore --search ""
13
- const filter = (search !== '') ? search : null;
14
- const isForHuman = (format === 'human');
22
+ const filter = search !== '' ? search : null;
23
+ const isForHuman = format === 'human';
15
24
 
16
25
  // TODO: drop when addons are migrated to the v4 API
17
26
  if (addonIdOrRealId != null) {
18
27
  const addonId = await resolveAddonId(addonIdOrRealId);
19
28
  if (isForHuman) {
20
- Logger.println(colors.blue('Waiting for addon logs…'));
21
- }
22
- else {
29
+ Logger.println(styleText('blue', 'Waiting for addon logs…'));
30
+ } else {
23
31
  throw new Error(`"${format}" format is not yet available for add-on logs`);
24
32
  }
25
33
  return LogV2.displayLogs({ appAddonId: addonId, since, until, filter, deploymentId });
@@ -28,7 +36,7 @@ export async function appLogs (params) {
28
36
  const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
29
37
 
30
38
  if (isForHuman) {
31
- Logger.println(colors.blue('Waiting for application logs…'));
39
+ Logger.println(styleText('blue', 'Waiting for application logs…'));
32
40
  }
33
41
 
34
42
  const deferred = new Deferred();
@@ -1,11 +1,11 @@
1
- import * as AppConfig from '../models/app_configuration.js';
1
+ import { styleText } from 'node:util';
2
2
  import { Logger } from '../logger.js';
3
- import colors from 'colors/safe.js';
3
+ import * as AppConfig from '../models/app_configuration.js';
4
4
 
5
- export async function makeDefault (params) {
5
+ export async function makeDefault(params) {
6
6
  const [alias] = params.args;
7
7
 
8
8
  await AppConfig.setDefault(alias);
9
9
 
10
- Logger.printSuccess(`The application ${colors.green(alias)} has been set as default`);
11
- };
10
+ Logger.printSuccess(`The application ${styleText('green', alias)} has been set as default`);
11
+ }