clever-tools 3.0.2 → 3.2.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.
@@ -38,6 +38,7 @@ async function addLinkedApplication (appData, alias, ignoreParentConfig) {
38
38
  app_id: appData.id,
39
39
  org_id: appData.ownerId,
40
40
  deploy_url: appData.deployment.httpUrl || appData.deployment.url,
41
+ git_ssh_url: appData.deployment.url,
41
42
  name: appData.name,
42
43
  alias: alias || slugify(appData.name),
43
44
  };
@@ -63,7 +64,6 @@ async function removeLinkedApplication (alias) {
63
64
  };
64
65
 
65
66
  function findApp (config, alias) {
66
-
67
67
  if (_.isEmpty(config.apps)) {
68
68
  throw new Error('There are no applications linked. You can add one with `clever link`');
69
69
  }
@@ -82,6 +82,18 @@ function findApp (config, alias) {
82
82
  return findDefaultApp(config);
83
83
  }
84
84
 
85
+ function checkAlreadyLinked (apps, name, alias) {
86
+ const appAliasExists = apps.some((app) => app.alias != null && app.alias === alias);
87
+ if (appAliasExists) {
88
+ throw new Error(`An application is already linked with the alias '${alias}'`);
89
+ }
90
+
91
+ const appNameExists = apps.some((app) => app.name === name);
92
+ if (appNameExists) {
93
+ throw new Error(`An application is already linked with the name '${name}'`);
94
+ }
95
+ }
96
+
85
97
  function findDefaultApp (config) {
86
98
  if (_.isEmpty(config.apps)) {
87
99
  throw new Error('There are no applications linked. You can add one with `clever link`');
@@ -163,6 +175,7 @@ module.exports = {
163
175
  loadApplicationConf,
164
176
  addLinkedApplication,
165
177
  removeLinkedApplication,
178
+ checkAlreadyLinked,
166
179
  findApp,
167
180
  getAppDetails,
168
181
  getMostNaturalName,
@@ -14,11 +14,13 @@ const User = require('./user.js');
14
14
  const { sendToApi } = require('../models/send-to-api.js');
15
15
 
16
16
  function listAvailableTypes () {
17
- return autocomplete.words(['docker', 'elixir', 'go', 'gradle', 'haskell', 'jar', 'maven', 'node', 'php', 'play1', 'play2', 'python', 'ruby', 'rust', 'sbt', 'static-apache', 'war']);
17
+ return autocomplete.words(['docker', 'elixir', 'go', 'gradle', 'haskell', 'jar', 'maven', 'meteor', 'node', 'php', 'play1', 'play2', 'python', 'ruby', 'rust', 'sbt', 'static-apache', 'war']);
18
18
  };
19
19
 
20
+ const AVAILABLE_ZONES = ['par', 'rbx', 'rbxhds', 'scw', 'jed', 'mtl', 'sgp', 'syd', 'wsw'];
21
+
20
22
  function listAvailableZones () {
21
- return autocomplete.words(['par', 'mtl']);
23
+ return autocomplete.words(AVAILABLE_ZONES);
22
24
  };
23
25
 
24
26
  function listAvailableAliases () {
@@ -241,6 +243,7 @@ module.exports = {
241
243
  listAvailableAliases,
242
244
  listAvailableFlavors,
243
245
  listAvailableTypes,
246
+ AVAILABLE_ZONES,
244
247
  listAvailableZones,
245
248
  listDependencies,
246
249
  __mergeScalabilityParameters: mergeScalabilityParameters,
@@ -11,7 +11,7 @@ async function getBest (appId, orgaId) {
11
11
  return getFavouriteDomain({ id: orgaId, appId }).then(sendToApi)
12
12
  .catch(async (e) => {
13
13
 
14
- if (e.status !== 404) {
14
+ if (e.response.status !== 404) {
15
15
  throw e;
16
16
  }
17
17
 
package/src/models/git.js CHANGED
@@ -5,7 +5,7 @@ const path = require('path');
5
5
 
6
6
  const _ = require('lodash');
7
7
  const git = require('isomorphic-git');
8
- const http = require('isomorphic-git/http/node');
8
+ const http = require('./isomorphic-http-with-agent.js');
9
9
  const { autocomplete } = require('cliparse');
10
10
 
11
11
  const slugify = require('slugify');
@@ -0,0 +1,19 @@
1
+ 'use strict';
2
+
3
+ const isomotphicHttp = require('isomorphic-git/http/node');
4
+ const https = require('https');
5
+
6
+ // We use our own HTTP plugin, so we can customize the agent used for requests and configure a long timeout (default is 5 seconds).
7
+
8
+ const agent = new https.Agent({
9
+ keepAlive: true,
10
+ timeout: 10 * 60 * 1000,
11
+ });
12
+
13
+ function request (params) {
14
+ return isomotphicHttp.request({ ...params, agent });
15
+ }
16
+
17
+ module.exports = {
18
+ request,
19
+ };
@@ -1,4 +1,4 @@
1
- const { getHostAndTokens } = require('./send-to-api.js');
1
+ const { getHostAndTokens, processError } = require('./send-to-api.js');
2
2
  const colors = require('colors/safe');
3
3
  const { Deferred } = require('./utils.js');
4
4
  const Logger = require('../logger.js');
@@ -9,6 +9,11 @@ const { ApplicationLogStream } = require('@clevercloud/client/cjs/streams/applic
9
9
  const THROTTLE_ELEMENTS = 2000;
10
10
  const THROTTLE_PER_IN_MILLISECONDS = 100;
11
11
 
12
+ const retryConfiguration = {
13
+ enabled: true,
14
+ maxRetryCount: 6,
15
+ };
16
+
12
17
  async function displayLogs (params) {
13
18
 
14
19
  const deferred = params.deferred || new Deferred();
@@ -20,6 +25,8 @@ async function displayLogs (params) {
20
25
  tokens,
21
26
  ownerId,
22
27
  appId,
28
+ connectionTimeout: 10_000,
29
+ retryConfiguration,
23
30
  since,
24
31
  until,
25
32
  deploymentId,
@@ -33,10 +40,10 @@ async function displayLogs (params) {
33
40
 
34
41
  logStream
35
42
  .on('open', (event) => {
36
- Logger.debug(`stream opened! ${JSON.stringify({ appId, filter, deploymentId })}`);
43
+ Logger.debug(colors.blue(`Logs stream (open) ${JSON.stringify({ appId, filter, deploymentId })}`));
37
44
  })
38
45
  .on('error', (event) => {
39
- Logger.error(`an error occured: ${event.detail}`);
46
+ Logger.debug(colors.red(`Logs stream (error) ${event.error.message}`));
40
47
  })
41
48
  .onLog((log) => {
42
49
  Logger.println(formatLogLine(log));
@@ -45,6 +52,7 @@ async function displayLogs (params) {
45
52
  // start() is blocking until end of stream
46
53
  logStream.start()
47
54
  .then((reason) => deferred.resolve())
55
+ .catch(processError)
48
56
  .catch((error) => deferred.reject(error));
49
57
 
50
58
  return logStream;
@@ -23,12 +23,22 @@ async function sendToApi (requestParams) {
23
23
  .then(prefixUrl(conf.API_HOST))
24
24
  .then(addOauthHeader(tokens))
25
25
  .then((requestParams) => {
26
- if (process.env.CLEVER_VERBOSE) {
27
- Logger.debug(`${requestParams.method.toUpperCase()} ${requestParams.url} ? ${JSON.stringify(requestParams.queryParams)}`);
28
- }
26
+ Logger.debug(`${requestParams.method.toUpperCase()} ${requestParams.url} ? ${JSON.stringify(requestParams.queryParams)}`);
29
27
  return requestParams;
30
28
  })
31
- .then((requestParams) => request(requestParams, { retry: 1 }));
29
+ .then(request)
30
+ .catch(processError);
31
+ }
32
+
33
+ function processError (error) {
34
+ const code = error.code ?? error?.cause?.code;
35
+ if (code === 'EAI_AGAIN') {
36
+ throw new Error('Cannot reach the Clever Cloud API, please check your internet connection.', { cause: error });
37
+ }
38
+ if (code === 'ECONNRESET') {
39
+ throw new Error('The connection to the Clever Cloud API was closed abruptly, please try again.', { cause: error });
40
+ }
41
+ throw error;
32
42
  }
33
43
 
34
44
  function sendToWarp10 (requestParams) {
@@ -45,4 +55,4 @@ async function getHostAndTokens () {
45
55
  };
46
56
  }
47
57
 
48
- module.exports = { sendToApi, sendToWarp10, getHostAndTokens };
58
+ module.exports = { sendToApi, sendToWarp10, getHostAndTokens, processError };