clever-tools 3.6.1 → 3.8.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 (45) hide show
  1. package/README.md +1 -7
  2. package/bin/clever.js +99 -47
  3. package/package.json +48 -50
  4. package/src/command-options.js +22 -3
  5. package/src/commands/accesslogs.js +114 -34
  6. package/src/commands/activity.js +70 -16
  7. package/src/commands/addon.js +153 -75
  8. package/src/commands/applications.js +83 -1
  9. package/src/commands/cancel-deploy.js +3 -3
  10. package/src/commands/config.js +6 -7
  11. package/src/commands/console.js +16 -4
  12. package/src/commands/curl.js +13 -16
  13. package/src/commands/delete.js +16 -6
  14. package/src/commands/deploy.js +9 -6
  15. package/src/commands/diag.js +68 -28
  16. package/src/commands/domain.js +13 -13
  17. package/src/commands/drain.js +42 -27
  18. package/src/commands/env.js +53 -24
  19. package/src/commands/logs.js +3 -3
  20. package/src/commands/notify-email.js +33 -18
  21. package/src/commands/open.js +3 -3
  22. package/src/commands/profile.js +29 -9
  23. package/src/commands/published-config.js +26 -15
  24. package/src/commands/restart.js +12 -5
  25. package/src/commands/scale.js +2 -3
  26. package/src/commands/service.js +42 -15
  27. package/src/commands/ssh.js +3 -3
  28. package/src/commands/status.js +72 -46
  29. package/src/commands/stop.js +3 -3
  30. package/src/commands/tcp-redirs.js +54 -18
  31. package/src/commands/webhooks.js +28 -13
  32. package/src/logger.js +9 -6
  33. package/src/models/addon.js +21 -12
  34. package/src/models/app_configuration.js +11 -3
  35. package/src/models/application.js +106 -7
  36. package/src/models/exit-strategy-option.js +24 -0
  37. package/src/models/json-array.js +28 -0
  38. package/src/models/log-v4.js +9 -29
  39. package/src/models/log.js +9 -2
  40. package/src/models/namespaces.js +20 -0
  41. package/src/models/organisation.js +0 -20
  42. package/src/models/utils.js +8 -1
  43. package/src/models/accesslogs.js +0 -54
  44. package/vendors/README_VENDORS.md +0 -18
  45. package/vendors/curlconverter-parse.js +0 -3709
@@ -3,7 +3,11 @@
3
3
  const colors = require('colors/safe');
4
4
 
5
5
  const AppConfig = require('../models/app_configuration.js');
6
+ const Application = require('../models/application.js');
7
+ const Organisation = require('../models/organisation.js');
6
8
  const Logger = require('../logger.js');
9
+ const formatTable = require('../format-table.js');
10
+ const { truncateWithEllipsis } = require('../models/utils.js');
7
11
 
8
12
  async function list (params) {
9
13
  const { 'only-aliases': onlyAliases, json } = params.options;
@@ -43,4 +47,82 @@ function formatApps (apps, onlyAliases, json) {
43
47
  }
44
48
  }
45
49
 
46
- module.exports = { list };
50
+ async function listAll (params) {
51
+ const { org: orgaIdOrName, format } = params.options;
52
+
53
+ const linkedApps = await AppConfig.loadApplicationConf().then((conf) => conf.apps);
54
+
55
+ const ownerId = (orgaIdOrName != null && orgaIdOrName.orga_name !== '')
56
+ ? await Organisation.getId(orgaIdOrName)
57
+ : null;
58
+
59
+ const allAppsPerOrg = await Application.getAllApps(ownerId);
60
+
61
+ // For each app, we try to find a corresponding local alias in the configuration file
62
+ const allAppsWithAliasPerOrg = allAppsPerOrg.map((org) => {
63
+ const applicationsWithAlias = org.applications.map((app) => {
64
+ const foundAlias = linkedApps.find((a) => a.app_id === app.app_id)?.alias;
65
+ return { ...app, alias: foundAlias ?? '' };
66
+ });
67
+ return { ...org, applications: applicationsWithAlias };
68
+ });
69
+
70
+ switch (format) {
71
+ case 'json': {
72
+ Logger.printJson(allAppsWithAliasPerOrg);
73
+ break;
74
+ }
75
+ case 'human':
76
+ default: {
77
+
78
+ const headers = ['APPLICATION ID', 'NAME', 'TYPE', 'ZONE', 'LOCAL ALIAS'];
79
+ const appNameWidth = 42;
80
+
81
+ // We calculate the maximum width of each column to format the table
82
+ const allApps = allAppsWithAliasPerOrg.flatMap((org) => org.applications);
83
+ const columnWidths = [
84
+ getPropertyMaxWidth(allApps, 'app_id'),
85
+ appNameWidth,
86
+ getPropertyMaxWidth(allApps, 'type'),
87
+ getPropertyMaxWidth(allApps, 'zone'),
88
+ getPropertyMaxWidth(allApps, 'alias'),
89
+ ];
90
+ const formatTableWithColumnWidth = formatTable(columnWidths);
91
+
92
+ allAppsWithAliasPerOrg.forEach((org) => {
93
+
94
+ Logger.println();
95
+
96
+ const applicationsPlural = org.applications.length !== 1 ? 'applications' : 'application';
97
+ const punctuation = org.applications.length > 0 ? ':' : '';
98
+
99
+ Logger.println(colors.blue(`• Organization '${org.name}' (${org.id}) with ${org.applications.length} ${applicationsPlural}${punctuation}`));
100
+
101
+ if (org.applications.length > 0) {
102
+ Logger.println();
103
+ Logger.println(formatTableWithColumnWidth([
104
+ headers,
105
+ ...org.applications.map((app) => [
106
+ app.app_id,
107
+ truncateWithEllipsis(appNameWidth, app.name),
108
+ app.type,
109
+ app.zone,
110
+ app.alias,
111
+ ]),
112
+ ]));
113
+ }
114
+ });
115
+
116
+ break;
117
+ }
118
+ }
119
+ }
120
+
121
+ function getPropertyMaxWidth (array, propertyName) {
122
+ return Math.max(...array.map((o) => o[propertyName].length));
123
+ }
124
+
125
+ module.exports = {
126
+ list,
127
+ listAll,
128
+ };
@@ -1,13 +1,13 @@
1
1
  'use strict';
2
2
 
3
- const AppConfig = require('../models/app_configuration.js');
3
+ const Application = require('../models/application.js');
4
4
  const Logger = require('../logger.js');
5
5
  const { getAllDeployments, cancelDeployment } = require('@clevercloud/client/cjs/api/v2/application.js');
6
6
  const { sendToApi } = require('../models/send-to-api.js');
7
7
 
8
8
  async function cancelDeploy (params) {
9
- const { alias } = params.options;
10
- const { ownerId, appId } = await AppConfig.getAppDetails({ alias });
9
+ const { alias, app: appIdOrName } = params.options;
10
+ const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
11
11
 
12
12
  const deployments = await getAllDeployments({ id: ownerId, appId, limit: 1 }).then(sendToApi);
13
13
 
@@ -2,7 +2,6 @@
2
2
 
3
3
  const application = require('@clevercloud/client/cjs/api/v2/application.js');
4
4
 
5
- const AppConfig = require('../models/app_configuration.js');
6
5
  const Application = require('../models/application.js');
7
6
  const ApplicationConfiguration = require('../models/application_configuration.js');
8
7
 
@@ -10,8 +9,8 @@ const { sendToApi } = require('../models/send-to-api.js');
10
9
 
11
10
  async function get (params) {
12
11
  const [configurationName] = params.args;
13
- const { alias } = params.options;
14
- const { ownerId, appId } = await AppConfig.getAppDetails({ alias });
12
+ const { alias, app: appIdOrName } = params.options;
13
+ const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
15
14
  const app = await Application.get(ownerId, appId);
16
15
 
17
16
  if (configurationName == null) {
@@ -24,8 +23,8 @@ async function get (params) {
24
23
 
25
24
  async function set (params) {
26
25
  const [configurationName, configurationValue] = params.args;
27
- const { alias } = params.options;
28
- const { ownerId, appId } = await AppConfig.getAppDetails({ alias });
26
+ const { alias, app: appIdOrName } = params.options;
27
+ const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
29
28
  const config = ApplicationConfiguration.getById(configurationName);
30
29
 
31
30
  if (config != null) {
@@ -36,8 +35,8 @@ async function set (params) {
36
35
  }
37
36
 
38
37
  async function update (params) {
39
- const { alias } = params.options;
40
- const { ownerId, appId } = await AppConfig.getAppDetails({ alias });
38
+ const { alias, app: appIdOrName } = params.options;
39
+ const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
41
40
  const options = ApplicationConfiguration.parseOptions(params.options);
42
41
 
43
42
  if (Object.keys(options).length === 0) {
@@ -1,18 +1,30 @@
1
1
  'use strict';
2
2
 
3
+ const Application = require('../models/application.js');
3
4
  const AppConfig = require('../models/app_configuration.js');
4
5
  const Logger = require('../logger.js');
5
6
  const openPage = require('open');
6
7
 
7
8
  async function openConsole (params) {
8
- const { alias } = params.options;
9
+ const { alias, app: appIdOrName } = params.options;
9
10
 
10
- const { ownerId, appId } = await AppConfig.getAppDetails({ alias });
11
+ const baseUrl = 'https://console.clever-cloud.com';
11
12
 
12
- Logger.println('Opening the console in your browser');
13
+ const { apps } = await AppConfig.loadApplicationConf();
14
+ // If no app is linked or asked, open the Console without any context
15
+ if (apps.length === 0 && !appIdOrName) {
16
+ Logger.println('Opening the Console in your browser');
17
+ await openPage(baseUrl, { wait: false });
18
+ return;
19
+ }
13
20
 
21
+ const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
14
22
  const prefixPath = (ownerId.startsWith('user_')) ? 'users/me' : `organisations/${ownerId}`;
15
- const url = `https://console.clever-cloud.com/${prefixPath}/applications/${appId}`;
23
+ const url = `${baseUrl}/${prefixPath}/applications/${appId}`;
24
+
25
+ Logger.debug(`URL: ${url}`);
26
+ Logger.println(`Opening the Console in your browser for application ${appId}`);
27
+
16
28
  await openPage(url, { wait: false });
17
29
  }
18
30
 
@@ -5,7 +5,7 @@ const { loadOAuthConf, conf } = require('../models/configuration.js');
5
5
  const { addOauthHeader } = require('@clevercloud/client/cjs/oauth.js');
6
6
  const Logger = require('../logger.js');
7
7
  const colors = require('colors/safe');
8
- const curlParser = require('../../vendors/curlconverter-parse.js');
8
+ const curlconverter = require('curlconverter');
9
9
 
10
10
  async function loadTokens () {
11
11
  const tokens = await loadOAuthConf();
@@ -49,7 +49,12 @@ async function curl () {
49
49
  return;
50
50
  }
51
51
 
52
- const requestParams = await parseCurlCommand(['curl', ...curlArgs]);
52
+ // WARNING: Version 3.x of curlconverter uses a fork of yargs.
53
+ // For "reasons", when the command has a help param, it stops the parsing and triggers a very short and localized version of some help (WAT?).
54
+ // That's why we remove the help param before parsing and "reinstate" it before execution.
55
+ const curlArgsNoHelp = curlArgs.filter((arg) => arg !== '--help' && arg !== '-h');
56
+ const curlCommand = ['curl', ...curlArgsNoHelp].join(' ');
57
+ const requestParams = await parseCurlCommand(curlCommand);
53
58
 
54
59
  // We only allow request to the respective API_HOST
55
60
  if (!requestParams.url.startsWith(conf.API_HOST)) {
@@ -78,23 +83,15 @@ async function curl () {
78
83
 
79
84
  async function parseCurlCommand (curlCommand) {
80
85
 
81
- const [request] = curlParser.parse(curlCommand);
82
- const url = request.urls[0];
86
+ const jsonString = curlconverter.toJsonString(curlCommand);
87
+ const curlRequestParams = JSON.parse(jsonString);
83
88
 
84
89
  return {
85
- method: url.method.toString(),
86
- url: url.urlWithoutQueryArray.toString(),
87
- headers: transformCurlConverterWordsToObject(request.headers.headers),
88
- queryParams: transformCurlConverterWordsToObject(url.queryDict),
90
+ method: curlRequestParams.method,
91
+ url: curlRequestParams.url,
92
+ headers: curlRequestParams.headers,
93
+ queryParams: curlRequestParams.queries,
89
94
  };
90
95
  }
91
96
 
92
- function transformCurlConverterWordsToObject (words = []) {
93
- return Object.fromEntries(
94
- words.map(([key, value]) => {
95
- return [key.toString(), value.toString()];
96
- }),
97
- );
98
- }
99
-
100
97
  module.exports = { curl };
@@ -5,13 +5,23 @@ const Application = require('../models/application.js');
5
5
  const Logger = require('../logger.js');
6
6
 
7
7
  async function deleteApp (params) {
8
- const { alias, yes: skipConfirmation } = params.options;
9
- const appDetails = await AppConfig.getAppDetails({ alias });
8
+ const { alias, app: appIdOrName, yes: skipConfirmation } = params.options;
9
+ const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
10
10
 
11
- await Application.deleteApp(appDetails, skipConfirmation);
12
- await Application.unlinkRepo(appDetails.alias);
13
-
14
- Logger.println('The application has been deleted');
11
+ const app = await Application.get(ownerId, appId);
12
+ if (app == null) {
13
+ Logger.println('The application doesn\'t exist');
14
+ }
15
+ else {
16
+ // delete app
17
+ await Application.deleteApp(app, skipConfirmation);
18
+ Logger.println('The application has been deleted');
19
+ // unlink app
20
+ const wasUnlinked = await AppConfig.removeLinkedApplication({ appId, alias });
21
+ if (wasUnlinked) {
22
+ Logger.println('The application has been unlinked');
23
+ }
24
+ }
15
25
  };
16
26
 
17
27
  module.exports = { deleteApp };
@@ -9,11 +9,14 @@ const Log = require('../models/log-v4.js');
9
9
  const Logger = require('../logger.js');
10
10
  const { getAllDeployments } = require('@clevercloud/client/cjs/api/v2/application.js');
11
11
  const { sendToApi } = require('../models/send-to-api.js');
12
+ const ExitStrategy = require('../models/exit-strategy-option.js');
12
13
 
13
14
  // Once the API call to redeploy() has been triggered successfully,
14
15
  // the rest (waiting for deployment state to evolve and displaying logs) is done with auto retry (resilient to network failures)
15
16
  async function deploy (params) {
16
- const { alias, branch: branchName, tag: tagName, quiet, force, follow, 'same-commit-policy': sameCommitPolicy } = params.options;
17
+ const { alias, branch: branchName, tag: tagName, quiet, force, follow, 'same-commit-policy': sameCommitPolicy, 'exit-on': exitOnDeploy } = params.options;
18
+
19
+ const exitStrategy = ExitStrategy.get(follow, exitOnDeploy);
17
20
 
18
21
  const appData = await AppConfig.getAppDetails({ alias });
19
22
  const { ownerId, appId } = appData;
@@ -36,9 +39,9 @@ async function deploy (params) {
36
39
  Logger.println(`The clever-cloud application is up-to-date (${colors.green(remoteHeadCommitId)})`);
37
40
  return;
38
41
  case 'restart':
39
- return restartOnSameCommit(ownerId, appId, commitIdToPush, quiet, follow, false);
42
+ return restartOnSameCommit(ownerId, appId, commitIdToPush, quiet, false, exitStrategy);
40
43
  case 'rebuild':
41
- return restartOnSameCommit(ownerId, appId, commitIdToPush, quiet, follow, true);
44
+ return restartOnSameCommit(ownerId, appId, commitIdToPush, quiet, true, exitStrategy);
42
45
  case 'error':
43
46
  default: {
44
47
  const upToDateMessage = `The clever-cloud application is up-to-date (${colors.green(remoteHeadCommitId)}).\nYou can set a policy with 'same-commit-policy' to handle differently when remote HEAD has the same commit as the one to push.\nOr try this command to restart the application:`;
@@ -79,12 +82,12 @@ async function deploy (params) {
79
82
  });
80
83
  Logger.println(colors.bold.green('Your source code has been pushed to Clever Cloud.'));
81
84
 
82
- return Log.watchDeploymentAndDisplayLogs({ ownerId, appId, commitId: commitIdToPush, knownDeployments, quiet, follow });
85
+ return Log.watchDeploymentAndDisplayLogs({ ownerId, appId, commitId: commitIdToPush, knownDeployments, quiet, exitStrategy });
83
86
  }
84
87
 
85
- async function restartOnSameCommit (ownerId, appId, commitIdToPush, quiet, follow, withoutCache) {
88
+ async function restartOnSameCommit (ownerId, appId, commitIdToPush, quiet, withoutCache, exitStrategy) {
86
89
  const restart = await Application.redeploy(ownerId, appId, commitIdToPush, withoutCache);
87
- return Log.watchDeploymentAndDisplayLogs({ ownerId, appId, deploymentId: restart.deploymentId, quiet, follow });
90
+ return Log.watchDeploymentAndDisplayLogs({ ownerId, appId, deploymentId: restart.deploymentId, quiet, exitStrategy });
88
91
  }
89
92
 
90
93
  async function getBranchToDeploy (branchName, tagName) {
@@ -10,47 +10,87 @@ const pkg = require('../../package.json');
10
10
  const User = require('../models/user.js');
11
11
  const { conf, loadOAuthConf } = require('../models/configuration.js');
12
12
 
13
- async function diag () {
13
+ async function diag (params) {
14
+ const { format } = params.options;
14
15
 
16
+ /** @type {string} */
15
17
  const userId = await User.getCurrentId().catch(() => null);
16
18
  const authDetails = await loadOAuthConf();
17
19
 
18
- Logger.println('clever-tools ' + colors.green(pkg.version));
19
- Logger.println('Node.js ' + colors.green(process.version));
20
+ function getAuthState () {
21
+ if (authDetails.token == null) {
22
+ return 'not connected';
23
+ }
24
+
25
+ if (userId == null) {
26
+ return 'authentication failed';
27
+ }
28
+
29
+ return 'authenticated';
30
+ }
20
31
 
21
- Logger.println('Platform ' + colors.green(os.platform()));
22
- Logger.println('Release ' + colors.green(os.release()));
23
- Logger.println('Architecture ' + colors.green(process.arch));
32
+ const formattedDiag = {
33
+ version: pkg.version,
34
+ nodeVersion: process.version,
35
+ platform: os.platform(),
36
+ release: os.release(),
37
+ arch: process.arch,
38
+ shell: process.env.SHELL,
39
+ isPackaged: process.pkg != null,
40
+ execPath: process.execPath,
41
+ configFile: conf.CONFIGURATION_FILE,
42
+ authSource: authDetails.source,
43
+ oAuthToken: authDetails.token,
44
+ authState: getAuthState(),
45
+ userId,
46
+ };
24
47
 
25
- // Linux specific
26
- const linuxInfos = await getLinuxInfos().then(({ pretty_name, name, id }) => pretty_name || name || id).catch(() => null);
48
+ const linuxInfos = await getLinuxInfos()
49
+ .then(({ pretty_name, name, id }) => pretty_name || name || id)
50
+ .catch(() => null);
27
51
  if (linuxInfos != null) {
28
- Logger.println('Linux ' + colors.green(linuxInfos));
52
+ formattedDiag.linuxInfos = linuxInfos;
29
53
  }
30
54
 
31
- Logger.println('Shell ' + colors.green(process.env.SHELL));
55
+ switch (format) {
56
+ case 'json': {
57
+ Logger.printJson(formattedDiag);
58
+ break;
59
+ }
60
+ case 'human':
61
+ default: {
62
+ Logger.println('clever-tools ' + colors.green(formattedDiag.version));
63
+ Logger.println('Node.js ' + colors.green(formattedDiag.nodeVersion));
64
+ Logger.println('Platform ' + colors.green(formattedDiag.platform));
65
+ Logger.println('Release ' + colors.green(formattedDiag.release));
66
+ Logger.println('Architecture ' + colors.green(formattedDiag.arch));
67
+ if (formattedDiag.linuxInfos != null) {
68
+ Logger.println('Linux ' + colors.green(formattedDiag.linuxInfos));
69
+ }
70
+ Logger.println('Shell ' + colors.green(formattedDiag.shell));
71
+ Logger.println('Packaged ' + colors.green(formattedDiag.isPackaged));
72
+ Logger.println('Exec path ' + colors.green(formattedDiag.execPath));
73
+ Logger.println('Config file ' + colors.green(formattedDiag.configFile));
32
74
 
33
- const isPackaged = (process.pkg != null);
34
- Logger.println('Packaged ' + colors.green(isPackaged));
35
- Logger.println('Exec path ' + colors.green(process.execPath));
36
- Logger.println('Config file ' + colors.green(conf.CONFIGURATION_FILE));
37
- Logger.println('Auth source ' + colors.green(authDetails.source));
75
+ Logger.println('Auth source ' + colors.green(formattedDiag.authSource));
38
76
 
39
- const oauthToken = (authDetails.token != null)
40
- ? colors.green(authDetails.token)
41
- : colors.red('(none)');
42
- Logger.println('oAuth token ' + oauthToken);
77
+ const token = formattedDiag.oAuthToken == null ? colors.red('(none)') : colors.green(formattedDiag.oAuthToken);
78
+ Logger.println('oAuth token ' + token);
43
79
 
44
- if (authDetails.token != null) {
45
- if (userId != null) {
46
- Logger.println('User ID ' + colors.green(userId));
80
+ switch (formattedDiag.authState) {
81
+ case 'authenticated': {
82
+ Logger.println('User ID ' + colors.green(formattedDiag.userId));
83
+ break;
84
+ }
85
+ case 'authentication failed': {
86
+ Logger.println('User ID ' + colors.red('Authentication failed'));
87
+ break;
88
+ }
89
+ case 'not connected': {
90
+ Logger.println('User ID ' + colors.red('Not connected'));
91
+ }
92
+ }
47
93
  }
48
- else {
49
- Logger.println('User ID ' + colors.red('Authentication failed'));
50
- }
51
- }
52
- else {
53
- Logger.println('User ID ' + colors.red('Not connected'));
54
94
  }
55
95
  }
56
96
 
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const AppConfig = require('../models/app_configuration.js');
3
+ const Application = require('../models/application.js');
4
4
  const Logger = require('../logger.js');
5
5
  const {
6
6
  get: getApp,
@@ -26,8 +26,8 @@ function getFavouriteDomain ({ ownerId, appId }) {
26
26
  }
27
27
 
28
28
  async function list (params) {
29
- const { alias } = params.options;
30
- const { ownerId, appId } = await AppConfig.getAppDetails({ alias });
29
+ const { alias, app: appIdOrName } = params.options;
30
+ const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
31
31
 
32
32
  const app = await getApp({ id: ownerId, appId }).then(sendToApi);
33
33
  const favouriteDomain = await getFavouriteDomain({ ownerId, appId });
@@ -41,8 +41,8 @@ async function list (params) {
41
41
 
42
42
  async function add (params) {
43
43
  const [fqdn] = params.args;
44
- const { alias } = params.options;
45
- const { ownerId, appId } = await AppConfig.getAppDetails({ alias });
44
+ const { alias, app: appIdOrName } = params.options;
45
+ const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
46
46
  const encodedFqdn = encodeURIComponent(fqdn);
47
47
 
48
48
  await addDomain({ id: ownerId, appId, domain: encodedFqdn }).then(sendToApi);
@@ -50,8 +50,8 @@ async function add (params) {
50
50
  }
51
51
 
52
52
  async function getFavourite (params) {
53
- const { alias } = params.options;
54
- const { ownerId, appId } = await AppConfig.getAppDetails({ alias });
53
+ const { alias, app: appIdOrName } = params.options;
54
+ const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
55
55
 
56
56
  const favouriteDomain = await getFavouriteDomain({ ownerId, appId });
57
57
 
@@ -64,16 +64,16 @@ async function getFavourite (params) {
64
64
 
65
65
  async function setFavourite (params) {
66
66
  const [fqdn] = params.args;
67
- const { alias } = params.options;
68
- const { ownerId, appId } = await AppConfig.getAppDetails({ alias });
67
+ const { alias, app: appIdOrName } = params.options;
68
+ const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
69
69
 
70
70
  await markFavouriteDomain({ id: ownerId, appId }, { fqdn }).then(sendToApi);
71
71
  Logger.println('Your favourite domain has been successfully set');
72
72
  }
73
73
 
74
74
  async function unsetFavourite (params) {
75
- const { alias } = params.options;
76
- const { ownerId, appId } = await AppConfig.getAppDetails({ alias });
75
+ const { alias, app: appIdOrName } = params.options;
76
+ const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
77
77
 
78
78
  await unmarkFavouriteDomain({ id: ownerId, appId }).then(sendToApi);
79
79
  Logger.println('Favourite domain has been successfully unset');
@@ -81,8 +81,8 @@ async function unsetFavourite (params) {
81
81
 
82
82
  async function rm (params) {
83
83
  const [fqdn] = params.args;
84
- const { alias } = params.options;
85
- const { ownerId, appId } = await AppConfig.getAppDetails({ alias });
84
+ const { alias, app: appIdOrName } = params.options;
85
+ const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
86
86
  const encodedFqdn = encodeURIComponent(fqdn);
87
87
 
88
88
  await removeDomain({ id: ownerId, appId, domain: encodedFqdn }).then(sendToApi);
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const AppConfig = require('../models/app_configuration.js');
3
+ const Application = require('../models/application.js');
4
4
  const { createDrainBody } = require('../models/drain.js');
5
5
  const Logger = require('../logger.js');
6
6
 
@@ -8,44 +8,59 @@ const { getDrains, createDrain, deleteDrain, updateDrainState } = require('@clev
8
8
  const { sendToApi } = require('../models/send-to-api.js');
9
9
 
10
10
  // TODO: This could be useful in other commands
11
- async function getAppOrAddonId ({ alias, addonId }) {
11
+ async function getAppOrAddonId ({ alias, appIdOrName, addonId }) {
12
12
  return (addonId != null)
13
13
  ? addonId
14
- : AppConfig.getAppDetails({ alias }).then(({ appId }) => appId);
14
+ : await Application.resolveId(appIdOrName, alias).then(({ appId }) => appId);
15
15
  }
16
16
 
17
17
  async function list (params) {
18
- const { alias, addon: addonId } = params.options;
18
+ const { alias, app: appIdOrName, addon: addonId, format } = params.options;
19
19
 
20
- const appIdOrAddonId = await getAppOrAddonId({ alias, addonId });
20
+ const appIdOrAddonId = await getAppOrAddonId({ alias, appIdOrName, addonId });
21
21
  const drains = await getDrains({ appId: appIdOrAddonId }).then(sendToApi);
22
22
 
23
- if (drains.length === 0) {
24
- Logger.println(`There are no drains for ${appIdOrAddonId}`);
25
- }
26
-
27
- drains.forEach((drain) => {
28
- const { id, state, target } = drain;
29
- const { url, drainType, indexPrefix, structuredDataParameters } = target;
23
+ switch (format) {
24
+ case 'json': {
25
+ const formattedDrains = drains.map((drain) => ({
26
+ id: drain.id,
27
+ target: drain.target,
28
+ state: drain.state,
29
+ }));
30
30
 
31
- let drainView = `${id} -> ${state} for ${url} as ${drainType}`;
32
- if (indexPrefix != null) {
33
- drainView += `, index: '${indexPrefix}-<YYYY-MM-DD>'`;
31
+ Logger.printJson(formattedDrains);
32
+ break;
34
33
  }
35
- if (structuredDataParameters != null) {
36
- drainView += `, sd-parameters: '${structuredDataParameters}'`;
34
+ case 'human':
35
+ default: {
36
+ if (drains.length === 0) {
37
+ Logger.println(`There are no drains for ${appIdOrAddonId}`);
38
+ }
39
+
40
+ drains.forEach((drain) => {
41
+ const { id, state, target } = drain;
42
+ const { url, drainType, indexPrefix, structuredDataParameters } = target;
43
+
44
+ let drainView = `${id} -> ${state} for ${url} as ${drainType}`;
45
+ if (indexPrefix != null) {
46
+ drainView += `, index: '${indexPrefix}-<YYYY-MM-DD>'`;
47
+ }
48
+ if (structuredDataParameters != null) {
49
+ drainView += `, sd-params: '${structuredDataParameters}'`;
50
+ }
51
+ Logger.println(drainView);
52
+ });
37
53
  }
38
- Logger.println(drainView);
39
- });
54
+ }
40
55
  }
41
56
 
42
57
  async function create (params) {
43
58
  const [drainTargetType, drainTargetURL] = params.args;
44
- const { alias, addon: addonId, username, password, 'api-key': apiKey, 'index-prefix': indexPrefix, 'sd-parameters': structuredDataParameters } = params.options;
59
+ const { alias, app: appIdOrName, addon: addonId, username, password, 'api-key': apiKey, 'index-prefix': indexPrefix, 'sd-params': structuredDataParameters } = params.options;
45
60
  const drainTargetCredentials = { username, password };
46
61
  const drainTargetConfig = { apiKey, indexPrefix, structuredDataParameters };
47
62
 
48
- const appIdOrAddonId = await getAppOrAddonId({ alias, addonId });
63
+ const appIdOrAddonId = await getAppOrAddonId({ alias, appIdOrName, addonId });
49
64
  const body = createDrainBody(appIdOrAddonId, drainTargetURL, drainTargetType, drainTargetCredentials, drainTargetConfig);
50
65
  await createDrain({ appId: appIdOrAddonId }, body).then(sendToApi);
51
66
 
@@ -54,9 +69,9 @@ async function create (params) {
54
69
 
55
70
  async function rm (params) {
56
71
  const [drainId] = params.args;
57
- const { alias, addon: addonId } = params.options;
72
+ const { alias, app: appIdOrName, addon: addonId } = params.options;
58
73
 
59
- const appIdOrAddonId = await getAppOrAddonId({ alias, addonId });
74
+ const appIdOrAddonId = await getAppOrAddonId({ alias, appIdOrName, addonId });
60
75
  await deleteDrain({ appId: appIdOrAddonId, drainId }).then(sendToApi);
61
76
 
62
77
  Logger.println('Your drain has been successfully removed');
@@ -64,9 +79,9 @@ async function rm (params) {
64
79
 
65
80
  async function enable (params) {
66
81
  const [drainId] = params.args;
67
- const { alias, addon: addonId } = params.options;
82
+ const { alias, app: appIdOrName, addon: addonId } = params.options;
68
83
 
69
- const appIdOrAddonId = await getAppOrAddonId({ alias, addonId });
84
+ const appIdOrAddonId = await getAppOrAddonId({ alias, appIdOrName, addonId });
70
85
  await updateDrainState({ appId: appIdOrAddonId, drainId }, { state: 'ENABLED' }).then(sendToApi);
71
86
 
72
87
  Logger.println('Your drain has been enabled');
@@ -74,9 +89,9 @@ async function enable (params) {
74
89
 
75
90
  async function disable (params) {
76
91
  const [drainId] = params.args;
77
- const { alias, addon: addonId } = params.options;
92
+ const { alias, app: appIdOrName, addon: addonId } = params.options;
78
93
 
79
- const appIdOrAddonId = await getAppOrAddonId({ alias, addonId });
94
+ const appIdOrAddonId = await getAppOrAddonId({ alias, appIdOrName, addonId });
80
95
  await updateDrainState({ appId: appIdOrAddonId, drainId }, { state: 'DISABLED' }).then(sendToApi);
81
96
 
82
97
  Logger.println('Your drain has been disabled');