@sap/cds-dk 7.4.1 → 7.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/bin/activate.js +1 -1
  2. package/bin/add.js +6 -4
  3. package/bin/build.js +4 -6
  4. package/bin/cds.js +4 -1
  5. package/bin/deploy/index.js +5 -2
  6. package/bin/eval.js +1 -1
  7. package/bin/extend.js +3 -3
  8. package/bin/login.js +2 -2
  9. package/bin/logout.js +1 -1
  10. package/bin/pull.js +1 -1
  11. package/bin/push.js +2 -2
  12. package/bin/subscribe.js +2 -2
  13. package/bin/unsubscribe.js +2 -2
  14. package/bin/upgrade.js +2 -2
  15. package/bin/version.js +2 -2
  16. package/bin/watch.js +1 -1
  17. package/lib/bind/bindingUtil.js +2 -1
  18. package/lib/bind/cfKeyProvider.js +1 -1
  19. package/lib/bind/userCdsrcJsonStorageProvider.js +1 -1
  20. package/lib/build/buildPlugin.js +6 -12
  21. package/lib/build/buildTaskEngine.js +24 -19
  22. package/lib/build/buildTaskFactory.js +27 -33
  23. package/lib/build/buildTaskProvider.js +1 -1
  24. package/lib/build/buildTaskProviderFactory.js +26 -41
  25. package/lib/build/constants.js +0 -1
  26. package/lib/build/index.js +3 -3
  27. package/lib/build/plugins.js +15 -15
  28. package/lib/build/provider/edmxBuildPlugin.js +6 -7
  29. package/lib/build/provider/fiori/index.js +8 -8
  30. package/lib/build/provider/hana/2migration.js +12 -16
  31. package/lib/build/provider/hana/index.js +5 -7
  32. package/lib/build/provider/hana/template/package.json +1 -1
  33. package/lib/build/provider/internalBuildPlugin.js +0 -8
  34. package/lib/build/provider/internalBuildTaskProvider.js +17 -21
  35. package/lib/build/provider/java/index.js +2 -1
  36. package/lib/build/provider/mtx-extension/index.js +3 -3
  37. package/lib/build/provider/mtx-sidecar/index.js +2 -1
  38. package/lib/build/provider/nodejs/index.js +6 -5
  39. package/lib/compile/openapi/csdl2openapi.js +29 -15
  40. package/lib/compile/openapi/index.js +6 -6
  41. package/lib/deploy/to-hana/hana.js +2 -2
  42. package/lib/env/schema.js +2 -3
  43. package/lib/index.js +68 -28
  44. package/lib/init/add.js +17 -0
  45. package/lib/init/constants.js +5 -3
  46. package/lib/init/index.js +39 -25
  47. package/lib/init/{util/merge.js → merge.js} +32 -20
  48. package/lib/init/{util/mvn.js → mvn.js} +5 -5
  49. package/lib/init/plugin.js +85 -0
  50. package/lib/init/projectReader.js +145 -0
  51. package/lib/init/registries/mta.js +151 -0
  52. package/lib/init/template/{kibana → application-logging}/files/mta.yaml.hbs +3 -3
  53. package/lib/init/template/application-logging/index.js +49 -0
  54. package/lib/init/template/approuter/files/mta.yaml.hbs +11 -11
  55. package/lib/init/template/approuter/files/xs-app.json.hbs +2 -2
  56. package/lib/init/template/approuter/index.js +36 -81
  57. package/lib/init/template/cf-manifest/files/manifest.yml.hbs +3 -3
  58. package/lib/init/template/cf-manifest/files/services-manifest.yml.hbs +4 -4
  59. package/lib/init/template/cf-manifest/index.js +4 -4
  60. package/lib/init/template/connectivity/index.js +22 -35
  61. package/lib/init/template/data/index.js +3 -2
  62. package/lib/init/template/destination/files/values.yaml +9 -0
  63. package/lib/init/template/destination/index.js +15 -47
  64. package/lib/init/template/enterprise-messaging/index.js +26 -58
  65. package/lib/init/template/enterprise-messaging-shared/index.js +23 -39
  66. package/lib/init/template/extensibility/index.js +16 -30
  67. package/lib/init/template/file-based-messaging/index.js +7 -8
  68. package/lib/init/template/h2/index.js +4 -4
  69. package/lib/init/template/hana/files/mta.yaml.hbs +8 -8
  70. package/lib/init/template/hana/index.js +29 -115
  71. package/lib/init/template/helm/files/chart/templates/NOTES.txt +12 -0
  72. package/lib/init/template/helm/files/chart/templates/_deployment_helpers.tpl +82 -0
  73. package/lib/init/template/helm/files/chart/templates/_helpers.tpl +28 -0
  74. package/lib/init/template/helm/files/chart/values.root.schema.json +61 -0
  75. package/lib/init/template/helm/files/chart/values.schema.json +366 -0
  76. package/lib/init/template/helm/{subcharts → files}/web-application/Chart.yaml +1 -1
  77. package/lib/init/template/helm/{subcharts → files}/web-application/templates/_api.tpl +1 -1
  78. package/lib/init/template/helm/{subcharts → files}/web-application/values.yaml +1 -1
  79. package/lib/init/template/helm/index.js +84 -85
  80. package/lib/init/template/helm-unified-runtime/files/Chart.yaml.hbs +10 -0
  81. package/lib/init/template/helm-unified-runtime/files/values.yaml.hbs +26 -0
  82. package/lib/init/template/helm-unified-runtime/index.js +91 -0
  83. package/lib/init/template/helm-unified-runtime/lib/build.js +0 -0
  84. package/lib/init/template/helm-unified-runtime/package.json +4 -0
  85. package/lib/init/template/html5-repo/files/values.yaml.hbs +28 -0
  86. package/lib/init/template/html5-repo/index.js +23 -97
  87. package/lib/init/template/java/index.js +3 -3
  88. package/lib/init/template/lint/index.js +2 -2
  89. package/lib/init/template/liquibase/index.js +16 -0
  90. package/lib/init/template/local-messaging/index.js +7 -8
  91. package/lib/init/template/mta/index.js +7 -19
  92. package/lib/init/template/mtx/index.js +2 -2
  93. package/lib/init/template/multitenancy/index.js +38 -89
  94. package/lib/init/template/nodejs/index.js +5 -4
  95. package/lib/init/template/notebook/index.js +1 -1
  96. package/lib/init/template/notifications/index.js +16 -19
  97. package/lib/init/template/pipeline/index.js +1 -1
  98. package/lib/init/template/postgres/index.js +25 -31
  99. package/lib/init/template/redis-messaging/index.js +23 -27
  100. package/lib/init/template/sample/index.js +4 -4
  101. package/lib/init/template/samples/index.js +2 -2
  102. package/lib/init/template/sqlite/files/{package.json.hbs → package.json} +0 -2
  103. package/lib/init/template/sqlite/index.js +6 -10
  104. package/lib/init/template/tiny-sample/index.js +6 -6
  105. package/lib/init/template/toggles/index.js +7 -8
  106. package/lib/init/template/typer/index.js +6 -6
  107. package/lib/init/template/xsuaa/files/mta.yaml.hbs +3 -3
  108. package/lib/init/template/xsuaa/files/values.yaml.hbs +3 -3
  109. package/lib/init/template/xsuaa/index.js +27 -52
  110. package/lib/init/{util/template.js → template.js} +1 -1
  111. package/lib/{client → mtx}/activate.js +15 -11
  112. package/lib/{client → mtx}/auth_manager.js +5 -4
  113. package/lib/{client → mtx}/download_legacy.js +6 -4
  114. package/lib/{client → mtx}/extend.js +14 -9
  115. package/lib/{client → mtx}/index.js +1 -1
  116. package/lib/{client → mtx}/params.js +3 -1
  117. package/lib/{client → mtx}/pull.js +6 -4
  118. package/lib/{client → mtx}/push.js +10 -9
  119. package/lib/{client → mtx}/settings_manager.js +8 -6
  120. package/lib/{client → mtx}/tenant_action.js +9 -8
  121. package/lib/{client/helper/cf_helper.js → mtx/util/cf.js} +4 -3
  122. package/lib/{client/helper/dependency_helper.js → mtx/util/dependencies.js} +1 -0
  123. package/lib/mtx/util/errors.js +27 -0
  124. package/lib/mtx/util/legacy_ext.js +16 -0
  125. package/lib/{client/helper/url_helper.js → mtx/util/urls.js} +12 -1
  126. package/lib/util/fs.js +5 -1
  127. package/lib/util/pruneAxiosErrors.js +35 -18
  128. package/lib/util/write.js +1 -1
  129. package/npm-shrinkwrap.json +310 -270
  130. package/package.json +1 -1
  131. package/lib/client/base_command.js +0 -54
  132. package/lib/init/template/_merging/registry-mta.js +0 -304
  133. package/lib/init/template/helm/Model.d.ts +0 -53
  134. package/lib/init/template/kibana/files/package.json.hbs +0 -17
  135. package/lib/init/template/kibana/index.js +0 -54
  136. package/lib/init/template/templateBase.js +0 -100
  137. package/lib/init/util/md5.js +0 -86
  138. package/lib/init/util/projectReader.js +0 -94
  139. /package/lib/init/{util/indent.js → indent.js} +0 -0
  140. /package/lib/init/template/helm/{subcharts → files}/content-deployment/Chart.yaml +0 -0
  141. /package/lib/init/template/helm/{subcharts → files}/content-deployment/templates/_helpers.tpl +0 -0
  142. /package/lib/init/template/helm/{subcharts → files}/content-deployment/templates/job.yaml +0 -0
  143. /package/lib/init/template/helm/{subcharts → files}/content-deployment/templates/secret.yaml +0 -0
  144. /package/lib/init/template/helm/{subcharts → files}/content-deployment/templates/service-account.yaml +0 -0
  145. /package/lib/init/template/helm/{subcharts → files}/content-deployment/templates/service-binding.yaml +0 -0
  146. /package/lib/init/template/helm/{subcharts → files}/content-deployment/values.schema.json +0 -0
  147. /package/lib/init/template/helm/{subcharts → files}/content-deployment/values.yaml +0 -0
  148. /package/lib/init/template/helm/{subcharts → files}/service-instance/Chart.yaml +0 -0
  149. /package/lib/init/template/helm/{subcharts → files}/service-instance/templates/_helpers.tpl +0 -0
  150. /package/lib/init/template/helm/{subcharts → files}/service-instance/templates/serviceinstance.yaml +0 -0
  151. /package/lib/init/template/helm/{subcharts → files}/service-instance/values.schema.json +0 -0
  152. /package/lib/init/template/helm/{subcharts → files}/service-instance/values.yaml +0 -0
  153. /package/lib/init/template/helm/{subcharts → files}/web-application/templates/NOTES.txt +0 -0
  154. /package/lib/init/template/helm/{subcharts → files}/web-application/templates/_helpers.tpl +0 -0
  155. /package/lib/init/template/helm/{subcharts → files}/web-application/templates/api-rule.yaml +0 -0
  156. /package/lib/init/template/helm/{subcharts → files}/web-application/templates/deployment.yaml +0 -0
  157. /package/lib/init/template/helm/{subcharts → files}/web-application/templates/network-policy.yaml +0 -0
  158. /package/lib/init/template/helm/{subcharts → files}/web-application/templates/pod-disruption-budget.yaml +0 -0
  159. /package/lib/init/template/helm/{subcharts → files}/web-application/templates/rbac.yaml +0 -0
  160. /package/lib/init/template/helm/{subcharts → files}/web-application/templates/secret.yaml +0 -0
  161. /package/lib/init/template/helm/{subcharts → files}/web-application/templates/service-account.yaml +0 -0
  162. /package/lib/init/template/helm/{subcharts → files}/web-application/templates/service-binding.yaml +0 -0
  163. /package/lib/init/template/helm/{subcharts → files}/web-application/templates/service.yaml +0 -0
  164. /package/lib/init/template/helm/{subcharts → files}/web-application/templates/virtual-service.yaml +0 -0
  165. /package/lib/init/template/helm/{subcharts → files}/web-application/values.schema.json +0 -0
  166. /package/lib/init/template/{helm/chart → helm-unified-runtime/files}/templates/NOTES.txt +0 -0
  167. /package/lib/init/template/{helm/chart → helm-unified-runtime/files}/templates/_deployment_helpers.tpl +0 -0
  168. /package/lib/init/template/{helm/chart → helm-unified-runtime/files}/templates/_helpers.tpl +0 -0
  169. /package/lib/init/template/{helm/chart → helm-unified-runtime/files}/values.root.schema.json +0 -0
  170. /package/lib/init/template/{helm/chart → helm-unified-runtime/files}/values.schema.json +0 -0
  171. /package/lib/init/template/postgres/files/{mta.yaml.hbs → mta.yml.hbs} +0 -0
  172. /package/lib/init/{util/xml.js → xml.js} +0 -0
  173. /package/lib/{client/helper/env_helper.js → mtx/util/env.js} +0 -0
  174. /package/lib/{client/helper/fs_helper.js → mtx/util/fs.js} +0 -0
  175. /package/lib/{client/helper → mtx/util}/logging.js +0 -0
  176. /package/lib/{client/helper → mtx/util}/question.js +0 -0
  177. /package/lib/{client/helper/string_helper.js → mtx/util/strings.js} +0 -0
  178. /package/lib/util/{cfUtil.js → cf.js} +0 -0
  179. /package/lib/util/{gitUtil.js → git.js} +0 -0
@@ -3,11 +3,13 @@ const { join } = require('path');
3
3
  const axios = require('axios');
4
4
 
5
5
  const { login } = require('./auth_manager');
6
- const BaseCommand = require('./base_command');
6
+
7
+ require('../util/pruneAxiosErrors');
8
+ const { handleHttpError } = require('./util/errors');
7
9
 
8
10
  const DOWNLOAD_FILE_NAME = 'migrated_projects.tgz'; // TODO try to add tenant later, if possible
9
11
 
10
- module.exports = class Download extends BaseCommand {
12
+ module.exports = class Download {
11
13
 
12
14
  static async run(paramValues) {
13
15
  const params = await login(paramValues);
@@ -15,7 +17,7 @@ module.exports = class Download extends BaseCommand {
15
17
  const projectFolder = params.get('projectFolder');
16
18
  const downloadPath = join(projectFolder, DOWNLOAD_FILE_NAME);
17
19
 
18
- if (fs.existsSync(downloadPath) && !(await require('./helper/question').askBooleanQuestion(`File ${DOWNLOAD_FILE_NAME} already exists. Continue (yN)? `, false, false))) {
20
+ if (fs.existsSync(downloadPath) && !(await require('./util/question').askBooleanQuestion(`File ${DOWNLOAD_FILE_NAME} already exists. Continue (yN)? `, false, false))) {
19
21
  console.log('Download cancelled');
20
22
  return;
21
23
  }
@@ -35,6 +37,6 @@ module.exports = class Download extends BaseCommand {
35
37
 
36
38
  return axios.post(downloadUrl, { tagRule, defaultTag }, options)
37
39
  .then(response => Buffer.from(response.data))
38
- .catch(error => this.handleHttpError(error, params, { url: downloadUrl }));
40
+ .catch(error => handleHttpError(error, params, { url: downloadUrl }));
39
41
  }
40
42
  }
@@ -3,12 +3,16 @@ const path = require('path');
3
3
  const axios = require('axios');
4
4
 
5
5
  const AuthManager = require('./auth_manager');
6
- const BaseCommand = require('./base_command');
7
- const { normalizePath, isParent } = require('./helper/fs_helper');
8
- const Question = require('./helper/question');
9
- const { getMessage } = require('./helper/logging');
6
+
7
+ require('../util/pruneAxiosErrors');
8
+ const { normalizePath, isParent } = require('./util/fs');
9
+ const Question = require('./util/question');
10
+ const { getMessage } = require('./util/logging');
11
+ const { handleHttpError } = require('./util/errors');
12
+ const { checkProject, getMtxApiUrl } = require('./util/legacy_ext');
10
13
 
11
14
  const COMMAND_URL_SUFFIX = 'content';
15
+ const CUSTOM_FILE_URL_SUFFIX = 'customTenantContent';
12
16
  const CUSTOM_FILE_FOLDERS = ['wsdl'];
13
17
  const DB_FOLDER = 'db';
14
18
  const SRV_FOLDER = 'srv';
@@ -19,9 +23,10 @@ function folderExists(folder) {
19
23
  '\nWhen using --force, make sure you are using a version control system (like git) to avoid data loss';
20
24
  }
21
25
 
22
- module.exports = class Extend extends BaseCommand {
26
+ module.exports = class Extend {
23
27
 
24
28
  static get COMMAND_URL_SUFFIX() { return COMMAND_URL_SUFFIX; }
29
+ static get CUSTOM_FILE_URL_SUFFIX() { return CUSTOM_FILE_URL_SUFFIX; }
25
30
 
26
31
  static async storeFiles(content, targetDirectory, filter) {
27
32
  fs.mkdirSync(targetDirectory, { recursive: true });
@@ -85,7 +90,7 @@ module.exports = class Extend extends BaseCommand {
85
90
  console.log('\n\nCreating extension project for', params.get('appUrl'), 'subdomain', params.get('subdomain'), 'in folder', params.get('projectFolder'));
86
91
  }
87
92
 
88
- const runOnExistingProject = await Extend.checkProject(params.get('projectFolder'));
93
+ const runOnExistingProject = await checkProject(params.get('projectFolder'));
89
94
  if (runOnExistingProject && !(params.get('force') || params.get('templates'))) {
90
95
  throw getMessage(folderExists(params.get('projectFolder')), { command: 'extend' });
91
96
  }
@@ -93,12 +98,12 @@ module.exports = class Extend extends BaseCommand {
93
98
  try {
94
99
  await Extend.runExtend(params);
95
100
  } catch (error) {
96
- await Extend.handleHttpError(error, params, { command: 'extend' });
101
+ await handleHttpError(error, params, { command: 'extend' });
97
102
  }
98
103
  }
99
104
 
100
105
  static async runExtend(params) {
101
- const contentUrl = Extend.getMtxApiUrl(params.get('appUrl'), COMMAND_URL_SUFFIX);
106
+ const contentUrl = getMtxApiUrl(params.get('appUrl'), COMMAND_URL_SUFFIX);
102
107
  const requestOptions = Object.assign({ retry: 0 }, params.get('reqAuth'));
103
108
 
104
109
  console.log('Retrieving files...');
@@ -134,7 +139,7 @@ module.exports = class Extend extends BaseCommand {
134
139
 
135
140
  if (params.get('wsdl')) {
136
141
  console.log('Writing custom files');
137
- const customFileUrl = Extend.getMtxApiUrl(params.get('appUrl'), Extend.CUSTOM_FILE_URL_SUFFIX);
142
+ const customFileUrl = getMtxApiUrl(params.get('appUrl'), CUSTOM_FILE_URL_SUFFIX);
138
143
  const customFiles = (await axios.get(customFileUrl, requestOptions)).data;
139
144
  await Extend.storeCustomFiles(params.get('projectFolder'), customFiles);
140
145
  }
@@ -1,8 +1,8 @@
1
1
  const Activate = require('./activate');
2
2
  const AuthManager = require('./auth_manager');
3
3
  const Extend = require('./extend');
4
- const Question = require('./helper/question');
5
4
  const { SettingsManager } = require('./settings_manager');
5
+ const Question = require('./util/question');
6
6
 
7
7
  module.exports = {
8
8
  extend: Extend.run,
@@ -1,6 +1,8 @@
1
1
  const cds = require('../cds');
2
+
3
+ const { escapeRegex } = require('./util/strings');
4
+
2
5
  const DEBUG = cds.debug('cli');
3
- const { escapeRegex } = require('./helper/string_helper');
4
6
 
5
7
 
6
8
  // PARAM BASE TYPES
@@ -6,10 +6,12 @@ const { join } = require('path');
6
6
  const axios = require('axios');
7
7
 
8
8
  const { login } = require('./auth_manager');
9
- const BaseCommand = require('./base_command');
10
- const { getMessage } = require('./helper/logging');
11
9
 
12
- module.exports = class Pull extends BaseCommand {
10
+ require('../util/pruneAxiosErrors');
11
+ const { getMessage } = require('./util/logging');
12
+ const { handleHttpError } = require('./util/errors');
13
+
14
+ module.exports = class Pull {
13
15
 
14
16
  static async run(paramValues) {
15
17
  if (!tar) {
@@ -46,7 +48,7 @@ module.exports = class Pull extends BaseCommand {
46
48
 
47
49
  return axios.post(pullUrl, {}, options)
48
50
  .then(response => Buffer.from(response.data))
49
- .catch(error => this.handleHttpError(error, params, { url: pullUrl }));
51
+ .catch(error => handleHttpError(error, params, { url: pullUrl }));
50
52
  }
51
53
 
52
54
  static getPackageJsonIndentation(packageContents) {
@@ -4,11 +4,13 @@ const { readFileSync, existsSync } = require('fs');
4
4
  const axios = require('axios');
5
5
 
6
6
  const { login } = require('./auth_manager');
7
- const BaseCommand = require('./base_command');
8
- const { getMessage } = require('./helper/logging');
9
- const { schemaRegex } = require('./helper/url_helper');
10
7
  const buildSystem = require('../build')
11
8
 
9
+ require('../util/pruneAxiosErrors');
10
+ const { getMessage } = require('./util/logging');
11
+ const { schemaRegex } = require('./util/urls');
12
+ const { handleHttpError } = require('./util/errors');
13
+
12
14
  const JOB_STATUS = {
13
15
  QUEUED: 'QUEUED',
14
16
  RUNNING: 'RUNNING',
@@ -16,7 +18,7 @@ const JOB_STATUS = {
16
18
  FAILED: 'FAILED'
17
19
  };
18
20
 
19
- module.exports = class Push extends BaseCommand {
21
+ module.exports = class Push {
20
22
 
21
23
  static async run(paramValues, pushOptions = {}) {
22
24
  const params = await login(paramValues);
@@ -35,8 +37,7 @@ module.exports = class Push extends BaseCommand {
35
37
 
36
38
  console.log(`\nPushing extension '${extensionName}' from`, { src }, 'to', target);
37
39
  const push = await this.pushTgz(params, content, extensionName);
38
- const async = params.get('async');
39
- if (async) {
40
+ if (params.get('async')) {
40
41
  await this.pollUntilFinished(push.headers.location, params)
41
42
  }
42
43
  console.log ('Activation succeeded.\n')
@@ -55,7 +56,7 @@ module.exports = class Push extends BaseCommand {
55
56
  try {
56
57
  content = (await axios.get(src, { responseEncoding: 'base64' })).data;
57
58
  } catch (error) {
58
- this.handleHttpError(error, params, { url: src });
59
+ handleHttpError(error, params, { url: src });
59
60
  }
60
61
  }
61
62
  return { src, content };
@@ -81,7 +82,7 @@ module.exports = class Push extends BaseCommand {
81
82
  extension: tgz,
82
83
  tag: extensionName
83
84
  }, options)
84
- .catch(error => this.handleHttpError(error, params, { url: pushUrl }));
85
+ .catch(error => handleHttpError(error, params, { url: pushUrl }));
85
86
  }
86
87
 
87
88
  static async pollUntilFinished(jobUrl, params) {
@@ -94,7 +95,7 @@ module.exports = class Push extends BaseCommand {
94
95
  }, 5 * 60 * 1000);
95
96
 
96
97
  const interval = setInterval(async () => {
97
- const { status, error } = (await axios.get(jobUrl, options)).data;
98
+ const { status, error = 'cds push failed' } = (await axios.get(jobUrl, options)).data;
98
99
  if (status === JOB_STATUS.FINISHED || status === JOB_STATUS.FAILED) {
99
100
  clearInterval(interval);
100
101
  clearTimeout(timeout);
@@ -4,13 +4,15 @@ const path = require('path');
4
4
  const axios = require('axios');
5
5
 
6
6
  const cds = require('../cds');
7
+
8
+ const { requireGlobal } = require('./util/dependencies');
9
+ const { getAppFromSuggestions, getSubdomain } = require('./util/cf');
10
+ const isBas = require('./util/env');
11
+ const Question = require('./util/question');
12
+ const { httpSchema, httpsSchema, schemaRegex, localhostRegex } = require('./util/urls');
13
+ const { capitalize } = require('./util/strings');
14
+
7
15
  const DEBUG = cds.debug('cli');
8
- const { requireGlobal } = require('./helper/dependency_helper');
9
- const { getAppFromSuggestions, getSubdomain } = require('./helper/cf_helper');
10
- const isBas = require('./helper/env_helper');
11
- const Question = require('./helper/question');
12
- const { httpSchema, httpsSchema, schemaRegex, localhostRegex } = require('./helper/url_helper');
13
- const { capitalize } = require('./helper/string_helper');
14
16
 
15
17
  const { ParamCollection, Persistence } = require('./params');
16
18
 
@@ -1,11 +1,13 @@
1
1
  const cds = require('../cds');
2
- const DEBUG = cds.debug('cli');
3
-
4
- const BaseCommand = require('./base_command');
5
- const { getMessage } = require('./helper/logging');
6
2
  const { ParamCollection } = require('./params');
7
3
  const AuthManager = require('./auth_manager');
8
- const { capitalize } = require('./helper/string_helper');
4
+
5
+ require('../util/pruneAxiosErrors');
6
+ const { getMessage } = require('./util/logging');
7
+ const { capitalize } = require('./util/strings');
8
+ const { handleHttpError } = require('./util/errors');
9
+
10
+ const DEBUG = cds.debug('cli');
9
11
 
10
12
  const COMMANDS = {
11
13
  subscribe: 'to',
@@ -13,7 +15,7 @@ const COMMANDS = {
13
15
  unsubscribe: 'from'
14
16
  };
15
17
 
16
- module.exports = class TenantAction extends BaseCommand {
18
+ module.exports = class TenantAction {
17
19
 
18
20
  // TODO JSDoc
19
21
  /**
@@ -23,7 +25,6 @@ module.exports = class TenantAction extends BaseCommand {
23
25
  if (!(command in COMMANDS)) {
24
26
  throw new Error(`invalid command: ${command}`);
25
27
  }
26
- super();
27
28
  this.command = command;
28
29
  this.gerund = command.replace(/e$/, 'ing');
29
30
  this.preposition = COMMANDS[command];
@@ -50,7 +51,7 @@ module.exports = class TenantAction extends BaseCommand {
50
51
  try {
51
52
  await require('axios').post(url, { tenant }, params.get('reqAuth'));
52
53
  } catch (error) {
53
- BaseCommand.handleHttpError(error, params, { url });
54
+ handleHttpError(error, params, { url });
54
55
  }
55
56
  }
56
57
 
@@ -2,10 +2,11 @@ const os = require('os');
2
2
  const { execFile } = require('child_process');
3
3
 
4
4
  const cds = require('../../cds');
5
- const DEBUG = cds.debug('cli');
6
5
  const Question = require('./question');
7
- const { formatObjectsFixedWidth } = require('./string_helper');
8
- const { schemaRegex } = require('./url_helper');
6
+ const { formatObjectsFixedWidth } = require('./strings');
7
+ const { schemaRegex } = require('./urls');
8
+
9
+ const DEBUG = cds.debug('cli');
9
10
 
10
11
  function runCf(args, callback) {
11
12
  const env = Object.assign({}, process.env, { LC_ALL: 'en_US.UTF-8' }); // enforce English headings
@@ -2,6 +2,7 @@ const os = require('os');
2
2
  const { execFileSync } = require('child_process');
3
3
 
4
4
  const cds = require('../../cds');
5
+
5
6
  const DEBUG = cds.debug('cli');
6
7
 
7
8
  let modulesDir;
@@ -0,0 +1,27 @@
1
+ const { getMessage } = require('./logging');
2
+
3
+ function handleHttpError(error, params, { url, command } = {}) {
4
+ url = url ?? params.get('appUrl');
5
+ const prefix = `Request to ${url} failed`;
6
+ switch (error.status) {
7
+ case 401:
8
+ throw getMessage(`${prefix}: invalid authentication.\nRetry with valid passcode${
9
+ params.has('passcodeUrl') ? ` from ${params.get('passcodeUrl')}` : ''
10
+ } or username/password (required if SaaS app is configured with mocked-auth).`, { error, command });
11
+ case 403:
12
+ throw getMessage(prefix + ': insufficient authorization. Ensure client has all necessary roles.', { error, command });
13
+ case 404:
14
+ throw getMessage(prefix + ': resource not found.', { error, command });
15
+ case 422:
16
+ // Compilation or native-extension error.
17
+ throw getMessage(prefix + '.', { error, command });
18
+ default:
19
+ // Unexpected error should be transparent to user.
20
+ delete error.status; // Purge extra property already included in message.
21
+ throw error;
22
+ }
23
+ }
24
+
25
+ module.exports = {
26
+ handleHttpError
27
+ };
@@ -0,0 +1,16 @@
1
+ const path = require('path');
2
+ const fs = require('fs').promises;
3
+
4
+ const { concatUrls } = require('./urls');
5
+ require('../../util/pruneAxiosErrors');
6
+
7
+ const MTX_URL_PATH_PREFIX = 'mtx/v1/model/';
8
+
9
+ module.exports = {
10
+ async checkProject(folder) {
11
+ return await fs.access(path.join(folder, 'package.json')).then(() => true).catch(() => false);
12
+ },
13
+ getMtxApiUrl(url, action) {
14
+ return concatUrls(url, MTX_URL_PATH_PREFIX, action);
15
+ }
16
+ }
@@ -12,10 +12,21 @@ function extractSubdomain(url) {
12
12
  return hostname.split('.')[0];
13
13
  }
14
14
 
15
+ function concatUrls(...parts) {
16
+ return parts
17
+ .map((p, i) => i === 0
18
+ ? p.replace(/\/$/ /*end slash*/, '')
19
+ : i === parts.length - 1
20
+ ? p.replace(/^\// /*begin slash*/, '')
21
+ : p.replace(/^\/|\/$/g /*both*/, ''))
22
+ .join('/');
23
+ }
24
+
15
25
  module.exports = {
16
26
  schemaRegex,
17
27
  localhostRegex,
18
28
  httpSchema,
19
29
  httpsSchema,
20
- extractSubdomain
30
+ extractSubdomain,
31
+ concatUrls
21
32
  };
package/lib/util/fs.js CHANGED
@@ -44,7 +44,11 @@ module.exports = new class FsUtil {
44
44
  const renderedFile = Mustache.render(file, project)
45
45
  return JSON.parse(renderedFile)
46
46
  }
47
- return JSON.parse(file)
47
+ try {
48
+ return JSON.parse(file)
49
+ } catch (error) {
50
+ throw new Error(error.message + '\n' + file)
51
+ }
48
52
  }
49
53
 
50
54
  async readJSONC(src) {
@@ -11,26 +11,43 @@ require('axios').interceptors.response.use(
11
11
  axError => {
12
12
  const { inspect } = require('util');
13
13
  const { url, method } = axError.config ?? {};
14
- const { response = {} } = axError;
15
- const { status, statusText } = response;
16
- let { data } = response;
17
- if (Buffer.isBuffer(data)) {
18
- data = data.toString();
19
- try {
20
- data = JSON.parse(data);
21
- } catch (error) { /* unexpected; data will be included in error below */ }
14
+ const { errno, code, response = {} } = axError;
15
+ const prefix = (url && method ? `${method.toUpperCase()} ${url} ` : '') + 'failed';
16
+
17
+ let error;
18
+ if (errno) {
19
+ // System error during request.
20
+ const message = prefix
21
+ + `: ${errno} ${code}`
22
+ + (code === 'ENOTFOUND' ? `. Make sure the URL is correct and the server is running.` : '');
23
+ error = stacklessError(message);
24
+ } else {
25
+ // Error after request has been made.
26
+ const { status, statusText } = response;
27
+ let { data } = response;
28
+ if (Buffer.isBuffer(data)) {
29
+ data = data.toString();
30
+ try {
31
+ data = JSON.parse(data);
32
+ } catch (error) { /* unexpected; data will be included in error below */
33
+ }
34
+ }
35
+ const inspectData = data && !data.error_description;
36
+ const reason = !inspectData && data?.error /* RFC 6749 */ && (typeof data.error === 'string' ? data.error : inspect(data.error));
37
+ const details = inspectData ? inspect(data) : data?.error_description /* RFC 6749 */;
38
+ const message = prefix +
39
+ (status || statusText ? ':' : '') +
40
+ (status ? ` ${status}` : '') +
41
+ (statusText ? ` ${statusText}` : '') +
42
+ (reason ? `. ${reason}` : '') +
43
+ (details ? `. Details: ${details}` : '');
44
+
45
+ error = stacklessError(message);
46
+ if (status) {
47
+ error.status = status;
48
+ }
22
49
  }
23
- const reason = data?.error /* RFC 6749 */ && (typeof data.error === 'string' ? data.error : inspect(data.error));
24
- const message = (url && method ? `${method.toUpperCase()} ${url} ` : '') +
25
- 'failed' +
26
- (status || statusText ? ':' : '') +
27
- (status ? ` ${status}` : '') +
28
- (statusText ? ` ${statusText}` : '') +
29
- (reason ? `. ${reason}` : '') +
30
- (data ? `. Details: '${data.error_description /* RFC 6749 */ || inspect(data)}'` : '');
31
50
 
32
- const error = stacklessError(message);
33
- error.status = status;
34
51
  if (require('../').debug('req')) {
35
52
  error.cause = axError;
36
53
  }
package/lib/util/write.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // eslint-disable-next-line no-unused-vars
2
- const USAGE = ()=>{ //NOSONAR
2
+ const USAGE = ()=>{
3
3
 
4
4
  // with a fully specified target file
5
5
  write ({foo:'bar'}) .to ('some/folder/foo.json')