@sap/cds-dk 6.0.4 → 6.1.3

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 (104) hide show
  1. package/CHANGELOG.md +60 -1
  2. package/bin/add.js +29 -16
  3. package/bin/compile/index.js +7 -2
  4. package/bin/fix-redirects.js +4 -2
  5. package/bin/init.js +5 -0
  6. package/bin/login.js +20 -4
  7. package/bin/pull.js +58 -0
  8. package/bin/push.js +52 -0
  9. package/bin/subscribe.js +45 -0
  10. package/lib/bind/bindingUtil.js +1 -2
  11. package/lib/cds.js +2 -3
  12. package/lib/client/activate.js +17 -16
  13. package/lib/client/auth_manager.js +10 -5
  14. package/lib/client/base_command.js +4 -6
  15. package/lib/client/extend.js +3 -2
  16. package/lib/client/helper/cf_helper.js +1 -0
  17. package/lib/client/helper/errors.js +11 -0
  18. package/lib/client/helper/logging.js +3 -10
  19. package/lib/client/helper/url_helper.js +7 -3
  20. package/lib/client/index.js +1 -1
  21. package/lib/client/params.js +9 -6
  22. package/lib/client/pull.js +48 -0
  23. package/lib/client/push.js +45 -0
  24. package/lib/client/settings_manager.js +81 -27
  25. package/lib/compile/openapi/csdl2openapi.js +135 -163
  26. package/lib/compile/openapi/index.js +0 -1
  27. package/lib/import/common.js +9 -1
  28. package/lib/import/odata/metadataconverter/MetadataConverter.js +17 -4
  29. package/lib/import/odata/v2parser.js +50 -26
  30. package/lib/import/odata/v4parser.js +110 -29
  31. package/lib/import/openapi/importOpenAPI.js +3 -3
  32. package/lib/init/constants.js +9 -3
  33. package/lib/init/template/_merging/registry-mta.js +284 -0
  34. package/lib/init/template/approuter/files/xs-app.json.hbs +7 -7
  35. package/lib/init/template/approuter/index.js +22 -32
  36. package/lib/init/template/auditlog/index.js +7 -9
  37. package/lib/init/template/data/index.js +2 -4
  38. package/lib/init/template/extensibility/files/cds.package.json +7 -0
  39. package/lib/init/template/extensibility/files/cds.package.json.hbs +9 -0
  40. package/lib/init/template/extensibility/files/xs-security.json.hbs +26 -0
  41. package/lib/init/template/extensibility/index.js +48 -0
  42. package/lib/init/template/hana/files/java/cdsrc.json.hbs +1 -1
  43. package/lib/init/template/hana/files/java/profile.cdsrc.json.hbs +2 -2
  44. package/lib/init/template/hana/files/mta.yaml.hbs +10 -0
  45. package/lib/init/template/hana/files/nodejs/cds.package.json.hbs +1 -1
  46. package/lib/init/template/hana/files/nodejs/cds.profile.package.json.hbs +2 -2
  47. package/lib/init/template/hana/index.js +74 -61
  48. package/lib/init/template/kibana-logging/index.js +31 -37
  49. package/lib/init/template/lint/files/.eslint/rules/no-entity-moo.js +14 -14
  50. package/lib/init/template/mta/files/mta.yaml.hbs +1 -1
  51. package/lib/init/template/mta/index.js +13 -7
  52. package/lib/init/template/mtx/index.js +2 -142
  53. package/lib/init/template/multitenancy/files/cds.package.json +7 -0
  54. package/lib/init/template/multitenancy/files/cds.package.json.hbs +9 -0
  55. package/lib/init/template/{mtx → multitenancy}/files/dependencies.package.json +1 -1
  56. package/lib/init/template/multitenancy/files/java/.cdsrc.json +19 -0
  57. package/lib/init/template/multitenancy/files/java/package.json +31 -0
  58. package/lib/init/template/{mtx → multitenancy}/files/mta.yaml.hbs +13 -6
  59. package/lib/init/template/multitenancy/files/xs-security.json.hbs +18 -0
  60. package/lib/init/template/multitenancy/index.js +109 -0
  61. package/lib/init/template/nodejs/files/package.json.hbs +4 -1
  62. package/lib/init/template/templateBase.js +2 -1
  63. package/lib/init/template/toggles/files/cds.package.json +7 -0
  64. package/lib/init/template/toggles/files/cds.package.json.hbs +9 -0
  65. package/lib/init/template/toggles/index.js +24 -0
  66. package/lib/init/template/xsuaa/files/mta.yaml.hbs +10 -0
  67. package/lib/init/template/xsuaa/index.js +44 -33
  68. package/lib/init/util/projectReader.js +12 -7
  69. package/lib/init/util/templateUtil.js +113 -111
  70. package/lib/k8s/ChartAdder.js +13 -3
  71. package/lib/k8s/ChartBuilder.js +6 -0
  72. package/lib/k8s/buildModel.js +1 -3
  73. package/lib/k8s/connectivity/index.js +5 -5
  74. package/lib/k8s/deployment/index.js +2 -4
  75. package/lib/k8s/deployment/subchart/Chart.yaml +1 -1
  76. package/lib/k8s/deployment/subchart/templates/_helpers.tpl +22 -11
  77. package/lib/k8s/deployment/subchart/templates/deployment.yaml +12 -5
  78. package/lib/k8s/deployment/subchart/templates/network-policy.yaml +3 -1
  79. package/lib/k8s/deployment/subchart/templates/pod-disruption-budget.yaml +1 -1
  80. package/lib/k8s/deployment/subchart/values.md +812 -0
  81. package/lib/k8s/deployment/subchart/values.schema.json +125 -30
  82. package/lib/k8s/deployment/subchart/values.yaml +7 -3
  83. package/lib/k8s/hana-deployer/index.js +10 -0
  84. package/lib/k8s/hana-deployer/templates/hana-deployer-job.yaml +8 -0
  85. package/lib/k8s/html5-apps-deployer/index.js +10 -0
  86. package/lib/k8s/html5-apps-deployer/templates/html5-apps-deployer-job.yaml +8 -0
  87. package/lib/k8s/index.js +2 -2
  88. package/lib/k8s/resources/helm/chart/schemas/values.root.schema.json +11 -0
  89. package/lib/k8s/resources/helm/chart/schemas/values.schema.json +479 -0
  90. package/lib/k8s/resources/helm/chart/templates/_deployment_helpers.tpl +1 -159
  91. package/lib/k8s/resources/helm/chart/templates/_helpers.tpl +0 -33
  92. package/lib/k8s/resources/helm/chart/templates/_sapcp_helpers.tpl +1 -1
  93. package/lib/lint/Linter.js +155 -158
  94. package/lib/lint/io.js +12 -5
  95. package/npm-shrinkwrap.json +214 -74
  96. package/package.json +5 -4
  97. package/lib/init/template/_merging/existences.js +0 -297
  98. package/lib/init/template/mtx/files/cds.package.json +0 -12
  99. package/lib/init/template/mtx/files/cds.package.json.hbs +0 -14
  100. package/lib/init/template/mtx/files/java/.cdsrc.json +0 -17
  101. package/lib/init/template/mtx/files/java/package.json +0 -43
  102. package/lib/init/template/mtx/files/java/server.js +0 -30
  103. package/lib/init/template/mtx/files/xs-security.json.hbs +0 -48
  104. package/lib/lint/.eslintrc.js +0 -3
package/CHANGELOG.md CHANGED
@@ -1,3 +1,4 @@
1
+
1
2
  # Change Log
2
3
 
3
4
  All notable changes to this project will be documented in this file.
@@ -6,6 +7,63 @@ This project adheres to [Semantic Versioning](http://semver.org/).
6
7
 
7
8
  The format is based on [Keep a Changelog](http://keepachangelog.com/).
8
9
 
10
+ ## Version 6.1.3 - 2022-09-06
11
+
12
+ ### Fixed
13
+
14
+ - `cds extend` and other commands no longer fail with `TypeError: Class constructor CliError cannot be invoked without 'new'`
15
+
16
+ ## Version 6.1.2 - 2022-08-25
17
+
18
+ ### Changed
19
+ - `cds init` uses latest Maven Java archetype version 1.27.1 for creating Java projects.
20
+
21
+ ### Fixed
22
+ - `cds add helm` fixed JSON Schema for `srv` property in values.yaml
23
+ - `cds add helm` fixed env property errors for `hana_deployer` and `html5_apps_deployer`
24
+ - `cds add data` now creates proper data file names for entites in a `context`, i.e. `sap.common-Countries.csv` instead of `sap-common-Countries.csv`
25
+ - `cds import` now captures the parameter/property of collection type differently and the associated annotations are pulled out of the `items` object of the parameter/property entry in the csn.
26
+ - Remove redundant `console.log()` statement in `cds lint`
27
+ - `cds push` now shows complete error messages from extension validation
28
+ - `cds push` and related commands now show properly formatted error messages and also fail with a non-zero exit code in error situations
29
+
30
+ ## Version 6.1.1 - 2022-08-11
31
+
32
+ ### Added
33
+
34
+ - `cds import` now supports OData and SAP annotations for OData V4 imports.
35
+ - `cds compile --to openapi` defines operation-specific HTTP error response status codes with descriptions via `ErrorResponses` property of certain annotations.
36
+ - `cds compile --to openapi` now supports `--openapi:servers` option.
37
+ - `cds add multitenancy` will add feature multitenancy-specific configuration, without extensibility.
38
+ - `cds add toggles` will add feature toggle-specific configuration.
39
+ - `cds add extensibility` will add configuration for project extensibility.
40
+ - `cds add helm` now supports resource configuration for HANA deployment job and HTML5 app deployment job.
41
+ - `cds add helm` added JSON Schema for values.yaml
42
+ - `cds pull` will download the current CDS model of an extended SaaS app running with @sap/cds-mtxs.
43
+ - `cds push` will upload an extension to a SaaS app running with @sap/cds-mtxs.
44
+
45
+ ### Changed
46
+
47
+ - `cds add helm` updated default resource requirements for both `java` and `nodejs` projects.
48
+ - `cds add helm` uses servicebinding.io bindings for CAP Java services, HANA and HTML5 app deployment jobs.
49
+ - `cds compile --to openapi` creates only component schemas for schemas referenced in operations and in other schemas.
50
+ - `cds import` switch from `@openapi.schema` to `@JSON.Schema`.
51
+ - `cds add mtx` will now add configuration for streamlined MTX. It effectively acts as a shortcut for `cds add multitenancy,toggles,extensibility`
52
+ - `cds add mtx` no longer includes `hana` and `xsuaa`. To achieve the same effect as before, run `cds add mtx && cds add hana,xsuaa --for production`.
53
+ - `cds bind -2 <xsuaa service instance>` binds the CDS `auth` service to the xsuaa instance. Previously `uaa` was used. This requires `@sap/cds` 6 or higher.
54
+ - `cds add lint:dev` updated to adjust to new api structure of `@sap/eslint-plugin-cds` v2.5.0
55
+ - `cds init` uses latest Maven Java archetype version 1.27.0 for creating Java projects.
56
+ - `cds login localhost:<port> -u <username>` now saves username (and empty password, if applicable) with project settings for convenience.
57
+
58
+ ### Fixed
59
+
60
+ - `cds add helm:connectivity`: `connectivity.configMapName` was not used for the `connectivity-proxy-info`.
61
+ - `cds import` replaced occurrences of `\\` with `/` in the `package.json` for Linux platforms.
62
+ - `cds import` fixed `@Core.Description` and `doc` property duplication.
63
+ - `cds extend` and `cds activate` no longer save any data (this is reserved to `cds login`).
64
+ - Extensibility commands now add http (not https) to local app URLs without schema.
65
+ - Extensibility commands don't query CF any longer when run against local apps.
66
+
9
67
  ## Version 6.0.4 - 2022-08-02
10
68
 
11
69
  ### Changed
@@ -14,7 +72,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
14
72
  - Use `@sap/cds` 6.0.4
15
73
  - `cds bind` handles orgs and spaces containing commas correctly.
16
74
 
17
-
18
75
  ## Version 6.0.3 - 2022-07-14
19
76
 
20
77
  ### Changed
@@ -24,6 +81,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
24
81
 
25
82
  ### Fixed
26
83
 
84
+ - `--vap-file` parameter of `cds deploy` is available again (removed in 6.0.0)
85
+ - `cds add helm:connectivity`: `connectivity.configMapName` was not used for the `connectivity-proxy-info`.
27
86
  - `--vcap-file` parameter of `cds deploy` is available again (removed in 6.0.0)
28
87
  - `cds add helm:connectivity`: `connectivity.configMapName` was not used for the `connectivity-proxy-info`.
29
88
  - `cds add helm:connectivity`: Environment variables added for connectivity service for Java.
package/bin/add.js CHANGED
@@ -13,30 +13,40 @@ module.exports = Object.assign(add, {
13
13
 
14
14
  The following <features> are supported so far:
15
15
 
16
- *hana* - adds configuration for SAP HANA deployment
16
+ *hana* - adds configuration for SAP HANA deployment
17
17
 
18
- *xsuaa* - adds configuration for authentication via XSUAA
18
+ *xsuaa* - adds configuration for authentication via XSUAA
19
19
 
20
- *mtx* - adds configuration for multitenancy and extensibility
20
+ *multitenancy* - adds configuration for multitenancy
21
21
 
22
- *approuter* - adds configuration for the Cloud Foundry approuter
22
+ *toggles* - adds configuration for feature toggles
23
23
 
24
- *mta* - adds an _mta.yaml_ file for MTA-based SAP Business Technology Platform deployment
24
+ *extensibility* - adds configuration for extensibility
25
25
 
26
- *cf-manifest* - adds _manifest.yml_ and _services-manifest.yml_ files for Cloud Foundry native deployment
26
+ *mtx* - adds configuration for multitenancy, feature toggles and extensibility
27
27
 
28
- This approach makes use of the 'Create-Service-Push Plugin' that has to be installed
29
- separately using _cf install-plugin Create-Service-Push_.
30
- _cf create-service-push_ creates the service(s) and pushes the application(s) to the
31
- SAP Business Technology Platform.
28
+ *approuter* - adds configuration for the Cloud Foundry approuter
32
29
 
33
- *pipeline* - adds files for CI/CD pipeline integration
30
+ *mta* - adds an _mta.yaml_ file for MTA-based SAP Business Technology Platform deployment
34
31
 
35
- *samples* - adds simple sample files
32
+ *cf-manifest* - adds _manifest.yml_ and _services-manifest.yml_ files for Cloud Foundry native deployment
36
33
 
37
- *notebook* - adds a Jupyter Notebook (beta)
34
+ This approach makes use of the 'Create-Service-Push Plugin' that has to be installed
35
+ separately using _cf install-plugin Create-Service-Push_.
36
+ _cf create-service-push_ creates the service(s) and pushes the application(s) to the
37
+ SAP Business Technology Platform.
38
+
39
+ *pipeline* - adds files for CI/CD pipeline integration
40
+
41
+ *samples* - adds simple sample files
42
+
43
+ *data* - adds data content for CSN model entities (as csv files)
44
+
45
+ *helm* - adds helm chart folder that contains the files needed to deploy the application using Kyma.
46
+
47
+ To add a specific feature in the helm chart you can use the command 'cds add helm:<featureName>'.
48
+ For example cds add helm:xsuaa and cds add helm:html5_apps_deployer.
38
49
 
39
- *data* - adds data content for CSN model entities (as csv files)
40
50
 
41
51
  # OPTIONS
42
52
 
@@ -56,10 +66,13 @@ module.exports = Object.assign(add, {
56
66
 
57
67
  # EXAMPLES
58
68
 
59
- *cds add* hana,mta,pipeline
60
- *cds add* mtx --for production
69
+ *cds add* mta,pipeline
70
+ *cds add* mtx
71
+ *cds add* hana,xsuaa --for production
61
72
  *cds add* cf-manifest
62
73
  *cds add* data --for my.namspace.MyEntity
74
+ *cds add* helm
75
+
63
76
 
64
77
  # SEE ALSO
65
78
 
@@ -1,6 +1,6 @@
1
1
  module.exports = Object.assign ( compile, {
2
2
  options: [
3
- '--from', '--service', '--lang', '--for', '--to', '--dest', '--log-level', '--flavor', '--dialect', '--sql-dialect', '--openapi:url'
3
+ '--from', '--service', '--lang', '--for', '--to', '--dest', '--log-level', '--flavor', '--dialect', '--sql-dialect', '--openapi:url', '--openapi:servers'
4
4
  ],
5
5
  shortcuts: [
6
6
  undefined, '-s', '-l', '-4', '-2', '-o', undefined, '-f'
@@ -105,6 +105,11 @@ module.exports = Object.assign ( compile, {
105
105
  base path as declared in the CDS source.
106
106
  Use the \${service-path} variable to have the service path included in the URL.
107
107
 
108
+ *--openapi:servers* <Stringified JSON Object for Open API export>
109
+
110
+ The servers definition used in the generated OpenAPI document. *--openapi:url* is
111
+ ignored when this option is specified.
112
+
108
113
  *--openapi:diagram*
109
114
 
110
115
  Include YUML diagram in the generated OpenAPI document, default: *false*.
@@ -278,7 +283,7 @@ function _log (messages, options) {
278
283
  const { sortMessagesSeverityAware, deduplicateMessages } = cds.compiler
279
284
  deduplicateMessages(messages)
280
285
  messages = sortMessagesSeverityAware (messages)
281
- cds.utils._log (messages, options)
286
+ cds._log (messages, options)
282
287
  }
283
288
 
284
289
  /* eslint no-console:0 */
@@ -1,5 +1,6 @@
1
1
  const [arg0, arg1, _, ...args] = process.argv // eslint-disable-line no-unused-vars
2
- const files = require('../lib/cds').resolve(args.length ? args : '*')
2
+ const cds = require('../lib/cds')
3
+ const files = cds.resolve(args.length ? args : '*')
3
4
  process.argv = [ arg0, arg1, 'ria', ...files ]
4
5
 
5
6
  console.log ('[cds] - searching for ambiguous redirects in', files)
@@ -7,6 +8,7 @@ const log = console.log; console.log = (...args) => {
7
8
  if (!log.found) log (log.found = '> found ambiguous redirects in these models -> please fix as follows:\n')
8
9
  log (...args)
9
10
  }
10
- require ('@sap/cds-compiler/bin/cdsv2m')
11
+
12
+ require(require.resolve ('@sap/cds-compiler/bin/cdsv2m', {paths: [ cds.home, process.cwd(), __dirname ]}))
11
13
 
12
14
  module.exports = ()=>{}
package/bin/init.js CHANGED
@@ -50,6 +50,11 @@ module.exports = Object.assign(init, {
50
50
 
51
51
  *notebook* - adds a Jupyter Notebook (beta)
52
52
 
53
+ *helm* - adds helm chart folder that contains the files needed to deploy the application using Kyma.
54
+
55
+ To add a specific feature in the helm chart you can use the command 'cds add helm:<featureName>'.
56
+ For example cds add helm:xsuaa and cds add helm:html5_apps_deployer.
57
+
53
58
  *--java:mvn* <Comma separated maven archetype specific parameters>
54
59
 
55
60
  Add the given parameters to the archetype call.
package/bin/login.js CHANGED
@@ -1,8 +1,8 @@
1
1
  const { bold } = require('../lib/util/term');
2
2
 
3
3
  module.exports = Object.assign(login, {
4
- options: ['--subdomain', '--directory', '--passcode', '--clientid'],
5
- shortcuts: ['-s', '-d', '-p', '-c'],
4
+ options: ['--subdomain', '--directory', '--passcode', '--user', '--clientid'],
5
+ shortcuts: ['-s', '-d', '-p', '-u', '-c'],
6
6
  flags: ['--plain'],
7
7
  get help() {
8
8
  const config = require('../lib/client/settings_manager').SettingsManager.config
@@ -71,6 +71,17 @@ module.exports = Object.assign(login, {
71
71
 
72
72
  Tenant-specific passcode for authentication.
73
73
 
74
+ *-u* | *--user* <name>[:[<password>]]
75
+
76
+ Username and optionally password for authentication with Basic Auth in test scenarios.
77
+ See https://cap.cloud.sap/docs/guides/multitenancy/#send-subscribe-events for information
78
+ on suitable mock users.
79
+
80
+ When typing the colon but omitting <password>, the password is assumed empty.
81
+
82
+ For security reasons, username will only be saved for app URLs that look like localhost.
83
+ The same is true for an empty password. Non-empty passwords will never be saved.
84
+
74
85
  *-c* | *--clientid* <clientid>
75
86
 
76
87
  Client ID for authentication. This will override the default Client ID from environment.
@@ -100,14 +111,19 @@ module.exports = Object.assign(login, {
100
111
 
101
112
 
102
113
  async function login ([url], options = {}) {
114
+ const [username, password] = options.user?.split(':') ?? [];
115
+ delete options.user;
103
116
  Object.assign(options, {
104
117
  url,
118
+ username,
119
+ password,
105
120
  tokenStorage: options.plain ? 'plain' : 'keyring',
106
- renewLogin: true
121
+ renewLogin: true,
122
+ saveData: true
107
123
  })
108
124
  delete options.plain
109
125
 
110
- await require('../lib/client/auth_manager').loginAndUpdateSettings(options)
126
+ await require('../lib/client/auth_manager').login(options)
111
127
  }
112
128
 
113
129
 
package/bin/pull.js ADDED
@@ -0,0 +1,58 @@
1
+ module.exports = Object.assign(pull, {
2
+ options: ['--directory', '--subdomain', '--passcode', '--username', '--clientid'],
3
+ flags: [],
4
+ shortcuts: ['-d', '-s', '-p', '-u', '-c'],
5
+ help: `
6
+ # SYNOPSIS
7
+
8
+ *cds pull* [ <app-url> ]
9
+
10
+ Pull the base model for your SaaS app extension.
11
+
12
+ To run this command, you need to obtain from the SaaS application provider:
13
+ - the app URL
14
+ - a template for your extension project.
15
+
16
+ Then create your extension project from the template and run *cds pull* to update your copy of the CDS model of the
17
+ SaaS app (also known as the base model).
18
+
19
+ To facilitate running this multiple times against the same app, refer to the *cds login* command.
20
+
21
+ If the app URL is omitted, it is determined from the current user's active CDS or Cloud Foundry login.
22
+
23
+
24
+ # OPTIONS
25
+
26
+ *-d* | *--directory* <project-extension-directory>
27
+
28
+ Specify the target directory of your extension project. By default, the current working directory is used.
29
+
30
+ *-s* | *--subdomain* <tenant-subdomain>
31
+
32
+ Specify your tenant's subdomain. By default, it's determined from the app URL.
33
+
34
+ *-p* | *--passcode* <passcode>
35
+
36
+ Tenant-specific passcode for authentication.
37
+
38
+ *-u* | *--username* <name>
39
+
40
+ Username for authentication with Basic Auth in test scenarios.
41
+
42
+ *-c* | *--clientid* <clientid>
43
+
44
+ Client ID for authentication. This will override the default Client ID from environment.
45
+
46
+ # SEE ALSO
47
+
48
+ *cds push* to push an extension to the SaaS app.
49
+
50
+ `})
51
+
52
+
53
+ async function pull([url], options = {}) {
54
+ await require('../lib/client/pull').run({
55
+ ...options,
56
+ url
57
+ })
58
+ }
package/bin/push.js ADDED
@@ -0,0 +1,52 @@
1
+ module.exports = Object.assign(push, {
2
+ options: ['--subdomain', '--passcode', '--username', '--clientid', '--to'],
3
+ flags: [],
4
+ shortcuts: ['-s', '-p', '-u', '-c'],
5
+ help: `
6
+ # SYNOPSIS
7
+
8
+ *cds push* [ <extension-project-directory> ]
9
+
10
+ Push your extension to the SaaS app in order to enable or update it.
11
+
12
+ By default, the current working directory is used as project directory.
13
+
14
+ To facilitate running this multiple times against the same app, refer to the *cds login* command.
15
+
16
+
17
+ # OPTIONS
18
+
19
+ *--to* <url>
20
+
21
+ Specify the URL of the extensible SaaS app. By default, it is determined from
22
+ the current user's active CDS or Cloud Foundry login.
23
+
24
+ *-s* | *--subdomain* <tenant-subdomain>
25
+
26
+ Specify your tenant's subdomain. By default, it's determined from project settings.
27
+
28
+ *-p* | *--passcode* <passcode>
29
+
30
+ Tenant-specific passcode for authentication.
31
+
32
+ *-u* | *--username* <name>
33
+
34
+ Username for authentication with Basic Auth in test scenarios.
35
+
36
+ *-c* | *--clientid* <clientid>
37
+
38
+ Client ID for authentication. This will override the default Client ID from environment.
39
+
40
+ # SEE ALSO
41
+
42
+ *cds pull* to get the CDS model of the SaaS app.
43
+
44
+ `})
45
+
46
+
47
+ async function push([projectFolder], options = {}) {
48
+ await require('../lib/client/push').run({
49
+ ...options,
50
+ projectFolder
51
+ })
52
+ }
@@ -0,0 +1,45 @@
1
+ module.exports = Object.assign(subscribe, {
2
+ options: ['--to', '--user'],
3
+ flags: [],
4
+ shortcuts: ['-2', '-u'],
5
+ help: `
6
+ # SYNOPSIS
7
+
8
+ *cds subscribe* <tenant>
9
+
10
+ Subscribe a tenant to a multi-tenant SaaS app.
11
+
12
+ *cds subscribe* only supports Basic Authentication and is intended for non-productive use,
13
+ including SaaS apps running on localhost with mock authentication.
14
+
15
+ # OPTIONS
16
+
17
+ *-2* | *--to* <url>
18
+
19
+ Specify the URL of the extensible SaaS app. Required setting.
20
+
21
+ *-u* | *--user* <name>[:<password>]
22
+
23
+ Username and optionally password for authentication. Required setting.
24
+ See https://cap.cloud.sap/docs/guides/multitenancy/#send-subscribe-events for information on suitable mock users.
25
+
26
+ If password is omitted, it is assumed empty.
27
+ Note: productive passwords should not be specified on the command line.
28
+
29
+ `})
30
+
31
+
32
+
33
+ async function subscribe([tenant], { to: url, user } = {}) {
34
+ const Logger = require('../lib/client/helper/logging');
35
+
36
+ if (!tenant) throw new Error('Must provide a tenant')
37
+ if (!url) throw new Error('Must provide an app URL via `--to`') // for now, if we don't infer it from the project
38
+ if (typeof user !== 'string') throw new Error('Must provide a username')
39
+ const [username, password = ''] = user.split(':');
40
+ Logger.log(`Subscribing to ${url} for tenant '${tenant}' with user '${username}'${password === '' ? ' and empty password' : ''}`);
41
+ const options = { auth: { username, password } };
42
+ return require('axios').post (url+'/-/cds/deployment/subscribe', { tenant }, options);
43
+ }
44
+
45
+ // cds subscribe t1 --to http://localhost:4004 -u yves
@@ -3,8 +3,7 @@ const os = require('os');
3
3
  const IS_WIN = os.platform() === 'win32';
4
4
 
5
5
  const KindToRequiresNameMap = {
6
- xsuaa: 'uaa',
7
- 'xsuaa-auth': 'uaa',
6
+ xsuaa: 'auth',
8
7
  'hana-cloud': 'db',
9
8
  hana: 'db',
10
9
  destinations: 'destinations',
package/lib/cds.js CHANGED
@@ -1,9 +1,8 @@
1
- /** @type { import('@sap/cds/apis/cds') } */
1
+ /** @type { import('@sap/cds/lib') } */
2
2
  const cds = module.exports = require(_local ('@sap/cds'))
3
3
 
4
4
  // for internal use in cds-dk only
5
- cds.utils._log = require(_local ('@sap/cds/bin/utils/log'))
6
-
5
+ cds._log = require(_local ('@sap/cds/bin/utils/log'))
7
6
 
8
7
  function _local (id) {
9
8
  return require.resolve (id, {paths:[
@@ -6,6 +6,7 @@ const AuthManager = require('./auth_manager');
6
6
  const BaseCommand = require('./base_command');
7
7
  const { collectFileContent, collectFiles, toUnixPath } = require('./helper/fs_helper');
8
8
  const Logger = require('./helper/logging');
9
+ const { CliError } = require('./helper/errors');
9
10
 
10
11
  const COMMAND_URL_SUFFIX = 'asyncActivate';
11
12
  const COMMAND_URL_SUFFIX_SYNC = 'activate';
@@ -27,7 +28,7 @@ async function checkFinished(jobId, statusUrl, params, finisher) {
27
28
  finisher.finished = true;
28
29
  clearInterval(finisher.timer);
29
30
  if (status === JOB_STATUS.FAILED) {
30
- return finisher.reject(new Error(`Job ${jobId} failed: ${error.message || JSON.stringify(error)}`));
31
+ return finisher.reject(new CliError(`Job ${jobId} failed: ${error.message || JSON.stringify(error)}`));
31
32
  }
32
33
  Logger.log('Extension active');
33
34
  finisher.resolve();
@@ -42,7 +43,7 @@ module.exports = class Activate extends BaseCommand {
42
43
 
43
44
  static async run(injection, paramValues) {
44
45
  try {
45
- const params = await AuthManager.loginAndUpdateSettings(paramValues);
46
+ const params = await AuthManager.login(paramValues);
46
47
 
47
48
  if (process.env.DEBUG) {
48
49
  Logger.log('Activating extension with parameters ' + JSON.stringify({
@@ -55,17 +56,17 @@ module.exports = class Activate extends BaseCommand {
55
56
  Logger.log(`Activating extension located at ${params.get('projectFolder')} to URL ${params.get('appUrl')}`);
56
57
  }
57
58
 
58
- if (!await Activate.checkProject(params.get('projectFolder'))) {
59
- throw new Error(params.get('projectFolder') + ' is not a valid extension project');
59
+ if (!await this.checkProject(params.get('projectFolder'))) {
60
+ throw new CliError(params.get('projectFolder') + ' is not a valid extension project');
60
61
  }
61
62
 
62
63
  try {
63
- await Activate.runActivate(injection.cds, params);
64
+ await this.runActivate(injection.cds, params);
64
65
  if (params.get('wsdl')) {
65
- await Activate.runCustomFileUpload(params);
66
+ await this.runCustomFileUpload(params);
66
67
  }
67
68
  } catch (error) {
68
- Activate.handleHttpError(error, params);
69
+ await this.handleHttpError(error, params);
69
70
  }
70
71
  } catch (error) {
71
72
  Logger.error(undefined, error);
@@ -153,7 +154,7 @@ module.exports = class Activate extends BaseCommand {
153
154
  return wsdlFiles;
154
155
  } catch (error) {
155
156
  Logger.error(undefined, error);
156
- throw new Error('No custom files found');
157
+ throw new CliError('No custom files found');
157
158
  }
158
159
  }
159
160
 
@@ -161,7 +162,7 @@ module.exports = class Activate extends BaseCommand {
161
162
  let activationUrl;
162
163
  const isSync = params.get('sync');
163
164
 
164
- return Activate.collectExtensionFiles(cds, params.get('projectFolder'))
165
+ return this.collectExtensionFiles(cds, params.get('projectFolder'))
165
166
  .then(allFiles => {
166
167
  if (allFiles.size === 0) {
167
168
  return null;
@@ -169,8 +170,8 @@ module.exports = class Activate extends BaseCommand {
169
170
 
170
171
  Logger.log('Activating extension...');
171
172
 
172
- const urlSuffix = isSync ? Activate.COMMAND_URL_SUFFIX_SYNC : Activate.COMMAND_URL_SUFFIX;
173
- activationUrl = Activate.getMtxApiUrl(params.get('appUrl'), urlSuffix);
173
+ const urlSuffix = isSync ? this.COMMAND_URL_SUFFIX_SYNC : this.COMMAND_URL_SUFFIX;
174
+ activationUrl = this.getMtxApiUrl(params.get('appUrl'), urlSuffix);
174
175
  const requestOptions = Object.assign({
175
176
  headers: {}
176
177
  }, params.get('reqAuth'));
@@ -189,17 +190,17 @@ module.exports = class Activate extends BaseCommand {
189
190
  const { jobID: jobId, statusPath } = response.data;
190
191
 
191
192
  if (jobId === undefined) {
192
- throw new Error('Activation failed: did not receive job ID');
193
+ throw new CliError('Activation failed: did not receive job ID');
193
194
  }
194
195
 
195
196
  if (!statusPath) {
196
- throw new Error(`Job ${jobId} failed: did not receive job-status path`);
197
+ throw new CliError(`Job ${jobId} failed: did not receive job-status path`);
197
198
  }
198
199
 
199
200
  Logger.debug(`Job ID: ${jobId}`);
200
201
 
201
202
  return new Promise((resolve, reject) => {
202
- const statusUrl = Activate.concatUrls(params.get('appUrl'), statusPath);
203
+ const statusUrl = this.concatUrls(params.get('appUrl'), statusPath);
203
204
  const finisher = {
204
205
  resolve,
205
206
  reject,
@@ -214,7 +215,7 @@ module.exports = class Activate extends BaseCommand {
214
215
  static async runCustomFileUpload(params) {
215
216
  Logger.log(`Uploading custom files to ${params.get('appUrl')}...`);
216
217
 
217
- const customFiles = Activate.collectCustomFiles(params.get('projectFolder'));
218
+ const customFiles = this.collectCustomFiles(params.get('projectFolder'));
218
219
 
219
220
  const customFilesSerialized = [];
220
221
  customFiles.forEach((value, key) => {
@@ -225,7 +226,7 @@ module.exports = class Activate extends BaseCommand {
225
226
  });
226
227
  });
227
228
 
228
- const customFileUrl = Activate.getMtxApiUrl(params.get('appUrl'), Activate.UPDATE_CUSTOM_FILE_URL_SUFFIX);
229
+ const customFileUrl = this.getMtxApiUrl(params.get('appUrl'), this.UPDATE_CUSTOM_FILE_URL_SUFFIX);
229
230
  const requestOptions = Object.assign({
230
231
  headers: {},
231
232
  }, params.get('reqAuth'));
@@ -4,6 +4,7 @@ const axios = require('axios');
4
4
  const Logger = require('./helper/logging');
5
5
  const { SettingsManager } = require('./settings_manager');
6
6
  const { ParamCollection } = require('./params');
7
+ const { CliError } = require('./helper/errors');
7
8
 
8
9
  function addTokenInfo(params, authData) {
9
10
  params.set('token', authData.access_token);
@@ -60,7 +61,7 @@ async function retrieveTokenOrPasscodeUrl(params) {
60
61
  try {
61
62
  response = await axios.get(tokenUrl);
62
63
  } catch (error) {
63
- throw new Error(`Failed to get authentication token: ${error}.\nResponse body: ${util.inspect(error.response && error.response.data)}`);
64
+ throw new CliError(`Failed to get authentication token: ${error}.\nResponse body: ${util.inspect(error.response && error.response.data)}`);
64
65
  }
65
66
  authData = response.data;
66
67
 
@@ -77,7 +78,7 @@ async function retrieveTokenOrPasscodeUrl(params) {
77
78
 
78
79
  module.exports = class AuthManager {
79
80
 
80
- static async loginAndUpdateSettings(paramValues) {
81
+ static async login(paramValues) {
81
82
  SettingsManager.init();
82
83
  const params = new ParamCollection(paramValues);
83
84
  await SettingsManager.loadAndMergeSettings(params);
@@ -86,15 +87,19 @@ module.exports = class AuthManager {
86
87
  } else {
87
88
  await retrieveTokenOrPasscodeUrl(params);
88
89
  if (!params.has('token')) {
89
- await SettingsManager.saveSettings(params);
90
- throw new Error('Failed to login: no valid token or passcode provided. ' +
90
+ if (params.get('saveData')) {
91
+ await SettingsManager.saveSettings(params);
92
+ }
93
+ throw new CliError('Failed to login: no valid token or passcode provided. ' +
91
94
  'Get a passcode' + (params.get('passcodeUrl') ? ' from ' + params.get('passcodeUrl') : '') +
92
95
  ' and supply the code when re-running the command');
93
96
  }
94
97
  params.set('reqAuth', { headers: { Authorization: 'Bearer ' + params.get('token') } });
95
98
  }
96
99
 
97
- await SettingsManager.saveSettings(params); // saves token conditionally
100
+ if (params.get('saveData')) {
101
+ await SettingsManager.saveSettings(params); // saves token conditionally
102
+ }
98
103
 
99
104
  return params;
100
105
  }
@@ -1,7 +1,7 @@
1
1
  const path = require('path');
2
2
  const fs = require('fs').promises;
3
3
 
4
- const Logger = require('./helper/logging');
4
+ const { CliError } = require('./helper/errors');
5
5
 
6
6
  const MTX_URL_PATH_PREFIX = 'mtx/v1/model/';
7
7
  const CUSTOM_FILE_URL_SUFFIX = 'customTenantContent';
@@ -22,15 +22,13 @@ module.exports = class BaseCommand {
22
22
 
23
23
  switch (error.response && error.response.status) {
24
24
  case 401:
25
- Logger.error('Request failed: authorization might have expired. Please retry with valid passcode' +
25
+ throw new CliError('Request failed: authorization might have expired. Please retry with valid passcode' +
26
26
  (params.has('passcodeUrl') ? ` from ${params.get('passcodeUrl')}` : ''), error);
27
- break;
28
27
  case 404:
29
- Logger.error(`Request failed. Please check application URL ${params.get('appUrl')}`, error);
30
- break;
28
+ throw new CliError(`Request failed. Please check application URL ${params.get('appUrl')}`, error);
31
29
  default:
32
30
  // Including 422 (compilation or native-extension error).
33
- Logger.error(undefined, error);
31
+ throw new CliError(undefined, error);
34
32
  }
35
33
  }
36
34