@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.
- package/CHANGELOG.md +60 -1
- package/bin/add.js +29 -16
- package/bin/compile/index.js +7 -2
- package/bin/fix-redirects.js +4 -2
- package/bin/init.js +5 -0
- package/bin/login.js +20 -4
- package/bin/pull.js +58 -0
- package/bin/push.js +52 -0
- package/bin/subscribe.js +45 -0
- package/lib/bind/bindingUtil.js +1 -2
- package/lib/cds.js +2 -3
- package/lib/client/activate.js +17 -16
- package/lib/client/auth_manager.js +10 -5
- package/lib/client/base_command.js +4 -6
- package/lib/client/extend.js +3 -2
- package/lib/client/helper/cf_helper.js +1 -0
- package/lib/client/helper/errors.js +11 -0
- package/lib/client/helper/logging.js +3 -10
- package/lib/client/helper/url_helper.js +7 -3
- package/lib/client/index.js +1 -1
- package/lib/client/params.js +9 -6
- package/lib/client/pull.js +48 -0
- package/lib/client/push.js +45 -0
- package/lib/client/settings_manager.js +81 -27
- package/lib/compile/openapi/csdl2openapi.js +135 -163
- package/lib/compile/openapi/index.js +0 -1
- package/lib/import/common.js +9 -1
- package/lib/import/odata/metadataconverter/MetadataConverter.js +17 -4
- package/lib/import/odata/v2parser.js +50 -26
- package/lib/import/odata/v4parser.js +110 -29
- package/lib/import/openapi/importOpenAPI.js +3 -3
- package/lib/init/constants.js +9 -3
- package/lib/init/template/_merging/registry-mta.js +284 -0
- package/lib/init/template/approuter/files/xs-app.json.hbs +7 -7
- package/lib/init/template/approuter/index.js +22 -32
- package/lib/init/template/auditlog/index.js +7 -9
- package/lib/init/template/data/index.js +2 -4
- package/lib/init/template/extensibility/files/cds.package.json +7 -0
- package/lib/init/template/extensibility/files/cds.package.json.hbs +9 -0
- package/lib/init/template/extensibility/files/xs-security.json.hbs +26 -0
- package/lib/init/template/extensibility/index.js +48 -0
- package/lib/init/template/hana/files/java/cdsrc.json.hbs +1 -1
- package/lib/init/template/hana/files/java/profile.cdsrc.json.hbs +2 -2
- package/lib/init/template/hana/files/mta.yaml.hbs +10 -0
- package/lib/init/template/hana/files/nodejs/cds.package.json.hbs +1 -1
- package/lib/init/template/hana/files/nodejs/cds.profile.package.json.hbs +2 -2
- package/lib/init/template/hana/index.js +74 -61
- package/lib/init/template/kibana-logging/index.js +31 -37
- package/lib/init/template/lint/files/.eslint/rules/no-entity-moo.js +14 -14
- package/lib/init/template/mta/files/mta.yaml.hbs +1 -1
- package/lib/init/template/mta/index.js +13 -7
- package/lib/init/template/mtx/index.js +2 -142
- package/lib/init/template/multitenancy/files/cds.package.json +7 -0
- package/lib/init/template/multitenancy/files/cds.package.json.hbs +9 -0
- package/lib/init/template/{mtx → multitenancy}/files/dependencies.package.json +1 -1
- package/lib/init/template/multitenancy/files/java/.cdsrc.json +19 -0
- package/lib/init/template/multitenancy/files/java/package.json +31 -0
- package/lib/init/template/{mtx → multitenancy}/files/mta.yaml.hbs +13 -6
- package/lib/init/template/multitenancy/files/xs-security.json.hbs +18 -0
- package/lib/init/template/multitenancy/index.js +109 -0
- package/lib/init/template/nodejs/files/package.json.hbs +4 -1
- package/lib/init/template/templateBase.js +2 -1
- package/lib/init/template/toggles/files/cds.package.json +7 -0
- package/lib/init/template/toggles/files/cds.package.json.hbs +9 -0
- package/lib/init/template/toggles/index.js +24 -0
- package/lib/init/template/xsuaa/files/mta.yaml.hbs +10 -0
- package/lib/init/template/xsuaa/index.js +44 -33
- package/lib/init/util/projectReader.js +12 -7
- package/lib/init/util/templateUtil.js +113 -111
- package/lib/k8s/ChartAdder.js +13 -3
- package/lib/k8s/ChartBuilder.js +6 -0
- package/lib/k8s/buildModel.js +1 -3
- package/lib/k8s/connectivity/index.js +5 -5
- package/lib/k8s/deployment/index.js +2 -4
- package/lib/k8s/deployment/subchart/Chart.yaml +1 -1
- package/lib/k8s/deployment/subchart/templates/_helpers.tpl +22 -11
- package/lib/k8s/deployment/subchart/templates/deployment.yaml +12 -5
- package/lib/k8s/deployment/subchart/templates/network-policy.yaml +3 -1
- package/lib/k8s/deployment/subchart/templates/pod-disruption-budget.yaml +1 -1
- package/lib/k8s/deployment/subchart/values.md +812 -0
- package/lib/k8s/deployment/subchart/values.schema.json +125 -30
- package/lib/k8s/deployment/subchart/values.yaml +7 -3
- package/lib/k8s/hana-deployer/index.js +10 -0
- package/lib/k8s/hana-deployer/templates/hana-deployer-job.yaml +8 -0
- package/lib/k8s/html5-apps-deployer/index.js +10 -0
- package/lib/k8s/html5-apps-deployer/templates/html5-apps-deployer-job.yaml +8 -0
- package/lib/k8s/index.js +2 -2
- package/lib/k8s/resources/helm/chart/schemas/values.root.schema.json +11 -0
- package/lib/k8s/resources/helm/chart/schemas/values.schema.json +479 -0
- package/lib/k8s/resources/helm/chart/templates/_deployment_helpers.tpl +1 -159
- package/lib/k8s/resources/helm/chart/templates/_helpers.tpl +0 -33
- package/lib/k8s/resources/helm/chart/templates/_sapcp_helpers.tpl +1 -1
- package/lib/lint/Linter.js +155 -158
- package/lib/lint/io.js +12 -5
- package/npm-shrinkwrap.json +214 -74
- package/package.json +5 -4
- package/lib/init/template/_merging/existences.js +0 -297
- package/lib/init/template/mtx/files/cds.package.json +0 -12
- package/lib/init/template/mtx/files/cds.package.json.hbs +0 -14
- package/lib/init/template/mtx/files/java/.cdsrc.json +0 -17
- package/lib/init/template/mtx/files/java/package.json +0 -43
- package/lib/init/template/mtx/files/java/server.js +0 -30
- package/lib/init/template/mtx/files/xs-security.json.hbs +0 -48
- 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*
|
|
16
|
+
*hana* - adds configuration for SAP HANA deployment
|
|
17
17
|
|
|
18
|
-
*xsuaa*
|
|
18
|
+
*xsuaa* - adds configuration for authentication via XSUAA
|
|
19
19
|
|
|
20
|
-
*
|
|
20
|
+
*multitenancy* - adds configuration for multitenancy
|
|
21
21
|
|
|
22
|
-
*
|
|
22
|
+
*toggles* - adds configuration for feature toggles
|
|
23
23
|
|
|
24
|
-
*
|
|
24
|
+
*extensibility* - adds configuration for extensibility
|
|
25
25
|
|
|
26
|
-
*
|
|
26
|
+
*mtx* - adds configuration for multitenancy, feature toggles and extensibility
|
|
27
27
|
|
|
28
|
-
|
|
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
|
-
*
|
|
30
|
+
*mta* - adds an _mta.yaml_ file for MTA-based SAP Business Technology Platform deployment
|
|
34
31
|
|
|
35
|
-
*
|
|
32
|
+
*cf-manifest* - adds _manifest.yml_ and _services-manifest.yml_ files for Cloud Foundry native deployment
|
|
36
33
|
|
|
37
|
-
|
|
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*
|
|
60
|
-
*cds add* mtx
|
|
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
|
|
package/bin/compile/index.js
CHANGED
|
@@ -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.
|
|
286
|
+
cds._log (messages, options)
|
|
282
287
|
}
|
|
283
288
|
|
|
284
289
|
/* eslint no-console:0 */
|
package/bin/fix-redirects.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const [arg0, arg1, _, ...args] = process.argv // eslint-disable-line no-unused-vars
|
|
2
|
-
const
|
|
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
|
-
|
|
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').
|
|
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
|
+
}
|
package/bin/subscribe.js
ADDED
|
@@ -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
|
package/lib/bind/bindingUtil.js
CHANGED
package/lib/cds.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
/** @type { import('@sap/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.
|
|
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:[
|
package/lib/client/activate.js
CHANGED
|
@@ -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
|
|
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.
|
|
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
|
|
59
|
-
throw new
|
|
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
|
|
64
|
+
await this.runActivate(injection.cds, params);
|
|
64
65
|
if (params.get('wsdl')) {
|
|
65
|
-
await
|
|
66
|
+
await this.runCustomFileUpload(params);
|
|
66
67
|
}
|
|
67
68
|
} catch (error) {
|
|
68
|
-
|
|
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
|
|
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
|
|
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 ?
|
|
173
|
-
activationUrl =
|
|
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
|
|
193
|
+
throw new CliError('Activation failed: did not receive job ID');
|
|
193
194
|
}
|
|
194
195
|
|
|
195
196
|
if (!statusPath) {
|
|
196
|
-
throw new
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
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
|
-
|
|
90
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
31
|
+
throw new CliError(undefined, error);
|
|
34
32
|
}
|
|
35
33
|
}
|
|
36
34
|
|