@sap/cds-dk 6.0.2 → 6.1.1
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 +63 -0
- package/bin/add.js +29 -16
- package/bin/cds.js +7 -3
- package/bin/compile/index.js +6 -1
- package/bin/deploy/index.js +7 -1
- package/bin/fix-redirects.js +4 -2
- package/bin/init.js +5 -0
- package/bin/login.js +8 -2
- package/bin/pull.js +58 -0
- package/bin/push.js +52 -0
- package/bin/subscribe.js +45 -0
- package/lib/bind/bindingResolver.js +1 -2
- package/lib/bind/bindingUtil.js +1 -2
- package/lib/bind/cfKeyProvider.js +3 -3
- package/lib/client/activate.js +1 -1
- package/lib/client/auth_manager.js +7 -3
- package/lib/client/extend.js +1 -1
- package/lib/client/helper/cf_helper.js +1 -0
- package/lib/client/helper/url_helper.js +7 -3
- package/lib/client/index.js +1 -1
- package/lib/client/params.js +4 -2
- package/lib/client/pull.js +51 -0
- package/lib/client/push.js +49 -0
- package/lib/client/settings_manager.js +74 -21
- 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 +0 -1
- package/lib/import/odata/v4parser.js +103 -29
- package/lib/import/openapi/importOpenAPI.js +3 -3
- package/lib/init/constants.js +9 -3
- package/lib/init/template/_merging/registry-mta.js +290 -0
- package/lib/init/template/approuter/index.js +22 -32
- package/lib/init/template/auditlog/index.js +7 -9
- 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 +76 -63
- 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/lint/index.js +1 -1
- 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 +3 -0
- package/lib/init/template/templateBase.js +4 -3
- 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 +13 -8
- package/lib/init/util/templateUtil.js +112 -110
- package/lib/k8s/ChartAdder.js +11 -3
- package/lib/k8s/ChartBuilder.js +6 -0
- package/lib/k8s/buildModel.js +1 -3
- package/lib/k8s/connectivity/index.js +11 -5
- package/lib/k8s/connectivity/templates/connectivity-proxy-info.yaml +7 -3
- 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/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/k8s/resources/helm/chart/values.schema.json +449 -0
- package/lib/k8s/xsuaa/lib.js +10 -7
- package/lib/lint/Linter.js +155 -158
- package/lib/lint/generators.js +1 -1
- package/lib/lint/io.js +13 -5
- package/npm-shrinkwrap.json +1053 -136
- 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,68 @@ 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.1 - 2022-08-11
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `cds import` now supports OData and SAP annotations for OData V4 imports.
|
|
15
|
+
- `cds compile --to openapi` defines operation-specific HTTP error response status codes with descriptions via `ErrorResponses` property of certain annotations.
|
|
16
|
+
- `cds compile --to openapi` now supports `--openapi:servers` option.
|
|
17
|
+
- `cds add multitenancy` will add feature multitenancy-specific configuration, without extensibility.
|
|
18
|
+
- `cds add toggles` will add feature toggle-specific configuration.
|
|
19
|
+
- `cds add extensibility` will add configuration for project extensibility.
|
|
20
|
+
- `cds add helm` now supports resource configuration for HANA deployment job and HTML5 app deployment job.
|
|
21
|
+
- `cds add helm` added JSON Schema for values.yaml
|
|
22
|
+
- `cds pull` will download the current CDS model of an extended SaaS app running with @sap/cds-mtxs.
|
|
23
|
+
- `cds push` will upload an extension to a SaaS app running with @sap/cds-mtxs.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- `cds add helm` updated default resource requirements for both `java` and `nodejs` projects.
|
|
28
|
+
- `cds add helm` uses servicebinding.io bindings for CAP Java services, HANA and HTML5 app deployment jobs.
|
|
29
|
+
- `cds compile --to openapi` creates only component schemas for schemas referenced in operations and in other schemas.
|
|
30
|
+
- `cds import` switch from `@openapi.schema` to `@JSON.Schema`.
|
|
31
|
+
- `cds add mtx` will now add configuration for streamlined MTX. It effectively acts as a shortcut for `cds add multitenancy,toggles,extensibility`
|
|
32
|
+
- `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`.
|
|
33
|
+
- `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.
|
|
34
|
+
- `cds add lint:dev` updated to adjust to new api structure of `@sap/eslint-plugin-cds` v2.5.0
|
|
35
|
+
- `cds init` uses latest Maven Java archetype version 1.27.0 for creating Java projects.
|
|
36
|
+
- `cds login localhost:<port> -u <username>` now saves username (and empty password, if applicable) with project settings for convenience.
|
|
37
|
+
|
|
38
|
+
### Fixed
|
|
39
|
+
|
|
40
|
+
- `cds add helm:connectivity`: `connectivity.configMapName` was not used for the `connectivity-proxy-info`.
|
|
41
|
+
- `cds import` replaced occurrences of `\\` with `/` in the `package.json` for Linux platforms.
|
|
42
|
+
- `cds import` fixed `@Core.Description` and `doc` property duplication.
|
|
43
|
+
- `cds extend` and `cds activate` no longer save any data (this is reserved to `cds login`).
|
|
44
|
+
- Extensibility commands now add http (not https) to local app URLs without schema.
|
|
45
|
+
- Extensibility commands don't query CF any longer when run against local apps.
|
|
46
|
+
|
|
47
|
+
## Version 6.0.4 - 2022-08-02
|
|
48
|
+
|
|
49
|
+
### Changed
|
|
50
|
+
|
|
51
|
+
- `cds init` uses latest Maven Java archetype version 1.26.1 for creating Java projects.
|
|
52
|
+
- Use `@sap/cds` 6.0.4
|
|
53
|
+
- `cds bind` handles orgs and spaces containing commas correctly.
|
|
54
|
+
|
|
55
|
+
## Version 6.0.3 - 2022-07-14
|
|
56
|
+
|
|
57
|
+
### Changed
|
|
58
|
+
|
|
59
|
+
- `cds init` uses latest Maven Java archetype version 1.26.0 for creating Java projects.
|
|
60
|
+
- `cds init` now creates Node.js projects with version 6 of `@sap/cds`
|
|
61
|
+
|
|
62
|
+
### Fixed
|
|
63
|
+
|
|
64
|
+
- `--vap-file` parameter of `cds deploy` is available again (removed in 6.0.0)
|
|
65
|
+
- `cds add helm:connectivity`: `connectivity.configMapName` was not used for the `connectivity-proxy-info`.
|
|
66
|
+
- `--vcap-file` parameter of `cds deploy` is available again (removed in 6.0.0)
|
|
67
|
+
- `cds add helm:connectivity`: `connectivity.configMapName` was not used for the `connectivity-proxy-info`.
|
|
68
|
+
- `cds add helm:connectivity`: Environment variables added for connectivity service for Java.
|
|
69
|
+
- `cds add helm`: Generation of `xs-security.json` file works on Windows now (`cds compile srv -2 xsuaa` command failed).
|
|
70
|
+
|
|
71
|
+
|
|
9
72
|
## Version 6.0.2 - 2022-07-06
|
|
10
73
|
|
|
11
74
|
### Changed
|
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/cds.js
CHANGED
|
@@ -67,8 +67,12 @@ const cli = { //NOSONAR
|
|
|
67
67
|
|
|
68
68
|
const DEBUG = /\b(cli)\b/.test (process.env.DEBUG) && console.error
|
|
69
69
|
|
|
70
|
-
function _local (id) {
|
|
71
|
-
return require.resolve (id, {paths:[process.cwd(), __dirname]})
|
|
70
|
+
function _local (id, _else) {
|
|
71
|
+
try { return require.resolve (id, {paths:[process.cwd(), __dirname]}) }
|
|
72
|
+
catch(e) {
|
|
73
|
+
if (_else) return _else(e)
|
|
74
|
+
else throw e
|
|
75
|
+
}
|
|
72
76
|
}
|
|
73
77
|
|
|
74
78
|
function _defaultCompile (argv, _force) {
|
|
@@ -80,7 +84,7 @@ function _defaultCompile (argv, _force) {
|
|
|
80
84
|
|
|
81
85
|
function _is_model (argv) {
|
|
82
86
|
// IMPORTANT: have a separate env here, so that the normal one is not initialized before `cds_cli.args` above
|
|
83
|
-
const env = require (_local('@sap/cds/lib/env')).for('cds')
|
|
87
|
+
const env = require (_local('@sap/cds/lib/env/cds-env', ()=>_local('@sap/cds/lib/env'))).for('cds')
|
|
84
88
|
const cds = require (_local('@sap/cds'))
|
|
85
89
|
return !!cds.resolve(argv,{env,cache:{}})
|
|
86
90
|
}
|
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*.
|
package/bin/deploy/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module.exports = Object.assign(deploy, {
|
|
2
|
-
options: ['--to', '--tunnel-address'],
|
|
2
|
+
options: ['--to', '--tunnel-address', '--vcap-file'],
|
|
3
3
|
flags: [ '--no-save', '--auto-undeploy', '--dry', '--with-mocks', '--store-credentials', '--bind' ],
|
|
4
4
|
shortcuts: ['-2'],
|
|
5
5
|
help: `
|
|
@@ -42,6 +42,12 @@ module.exports = Object.assign(deploy, {
|
|
|
42
42
|
Deploy through the given address (host:port) rather than the original
|
|
43
43
|
database address. The tunnel must have been opened before, e.g. using 'cf ssh'.
|
|
44
44
|
|
|
45
|
+
*--vcap-file* (beta feature)
|
|
46
|
+
|
|
47
|
+
Use credentials from the given file when deploying to *SAP HANA*, instead of
|
|
48
|
+
creating new credentials. File must be in *default-env.json* format, with a root
|
|
49
|
+
node *VCAP_SERVICES*.
|
|
50
|
+
|
|
45
51
|
*--store-credentials* (only in combination with *--to hana*)
|
|
46
52
|
|
|
47
53
|
Stores credentials in *default-env.json file*. This is the former default behavior
|
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
|
@@ -71,6 +71,11 @@ module.exports = Object.assign(login, {
|
|
|
71
71
|
|
|
72
72
|
Tenant-specific passcode for authentication.
|
|
73
73
|
|
|
74
|
+
*-u* | *--username* <name>
|
|
75
|
+
|
|
76
|
+
Username for authentication with Basic Auth in test scenarios. For security reasons,
|
|
77
|
+
username will only be saved for app URLs that look like localhost.
|
|
78
|
+
|
|
74
79
|
*-c* | *--clientid* <clientid>
|
|
75
80
|
|
|
76
81
|
Client ID for authentication. This will override the default Client ID from environment.
|
|
@@ -103,11 +108,12 @@ async function login ([url], options = {}) {
|
|
|
103
108
|
Object.assign(options, {
|
|
104
109
|
url,
|
|
105
110
|
tokenStorage: options.plain ? 'plain' : 'keyring',
|
|
106
|
-
renewLogin: true
|
|
111
|
+
renewLogin: true,
|
|
112
|
+
saveData: true
|
|
107
113
|
})
|
|
108
114
|
delete options.plain
|
|
109
115
|
|
|
110
|
-
await require('../lib/client/auth_manager').
|
|
116
|
+
await require('../lib/client/auth_manager').login(options)
|
|
111
117
|
}
|
|
112
118
|
|
|
113
119
|
|
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 = ''] = /([^:]+)(:(.*))?/.exec(user);
|
|
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
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
const Config = require('@sap/cds/lib/env')
|
|
2
1
|
const cds = require('../cds')
|
|
3
2
|
const LOG = cds.log('bind');
|
|
4
3
|
const resolveBinding = resolver(LOG);
|
|
5
4
|
const { platformText, bindingText } = require('./bindingUtil');
|
|
6
5
|
|
|
7
6
|
function getUnresolvedBindings({cwd = process.cwd(), env}) {
|
|
8
|
-
if (!env) env =
|
|
7
|
+
if (!env) env = cds.env.for('cds', cwd)
|
|
9
8
|
if (feature(env) === false || feature(env) === "false") return {}
|
|
10
9
|
|
|
11
10
|
const bindings = {}
|
package/lib/bind/bindingUtil.js
CHANGED
|
@@ -89,13 +89,13 @@ class CFKeyProvider {
|
|
|
89
89
|
|
|
90
90
|
|
|
91
91
|
const { org, space } = target;
|
|
92
|
-
const orgs = await this._req(targetWithAuth, `/v3/organizations?names=${org}`);
|
|
92
|
+
const orgs = await this._req(targetWithAuth, `/v3/organizations?names=${encodeURIComponent(encodeURIComponent(org))}`);
|
|
93
93
|
if (!(orgs && orgs.resources.length === 1)) {
|
|
94
94
|
throw new Error(`CF org ${org} not found!`);
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
const orgGuid = orgs.resources[0].guid;
|
|
98
|
-
const spaces = await this._req(targetWithAuth, `/v3/spaces?names=${space}&organization_guids=${orgGuid}`)
|
|
98
|
+
const spaces = await this._req(targetWithAuth, `/v3/spaces?names=${encodeURIComponent(encodeURIComponent(space))}&organization_guids=${encodeURIComponent(encodeURIComponent(orgGuid))}`)
|
|
99
99
|
if (!(spaces && spaces.resources.length === 1)) {
|
|
100
100
|
throw new Error(`CF space ${space} not found in org ${org}!`);
|
|
101
101
|
}
|
|
@@ -243,7 +243,7 @@ class BatchRequest {
|
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
const params = Object.keys(filterParams).map(
|
|
246
|
-
name => `${name}=${filterParams[name].map(value => encodeURIComponent(value)).join(',')}`
|
|
246
|
+
name => `${name}=${encodeURIComponent(filterParams[name].map(value => encodeURIComponent(value)).join(','))}`
|
|
247
247
|
).join("&");
|
|
248
248
|
|
|
249
249
|
const url = this.url + (this.url.match(/\?/) ? '&' : '?') + params;
|
package/lib/client/activate.js
CHANGED
|
@@ -42,7 +42,7 @@ module.exports = class Activate extends BaseCommand {
|
|
|
42
42
|
|
|
43
43
|
static async run(injection, paramValues) {
|
|
44
44
|
try {
|
|
45
|
-
const params = await AuthManager.
|
|
45
|
+
const params = await AuthManager.login(paramValues);
|
|
46
46
|
|
|
47
47
|
if (process.env.DEBUG) {
|
|
48
48
|
Logger.log('Activating extension with parameters ' + JSON.stringify({
|
|
@@ -77,7 +77,7 @@ async function retrieveTokenOrPasscodeUrl(params) {
|
|
|
77
77
|
|
|
78
78
|
module.exports = class AuthManager {
|
|
79
79
|
|
|
80
|
-
static async
|
|
80
|
+
static async login(paramValues) {
|
|
81
81
|
SettingsManager.init();
|
|
82
82
|
const params = new ParamCollection(paramValues);
|
|
83
83
|
await SettingsManager.loadAndMergeSettings(params);
|
|
@@ -86,7 +86,9 @@ module.exports = class AuthManager {
|
|
|
86
86
|
} else {
|
|
87
87
|
await retrieveTokenOrPasscodeUrl(params);
|
|
88
88
|
if (!params.has('token')) {
|
|
89
|
-
|
|
89
|
+
if (params.get('saveData')) {
|
|
90
|
+
await SettingsManager.saveSettings(params);
|
|
91
|
+
}
|
|
90
92
|
throw new Error('Failed to login: no valid token or passcode provided. ' +
|
|
91
93
|
'Get a passcode' + (params.get('passcodeUrl') ? ' from ' + params.get('passcodeUrl') : '') +
|
|
92
94
|
' and supply the code when re-running the command');
|
|
@@ -94,7 +96,9 @@ module.exports = class AuthManager {
|
|
|
94
96
|
params.set('reqAuth', { headers: { Authorization: 'Bearer ' + params.get('token') } });
|
|
95
97
|
}
|
|
96
98
|
|
|
97
|
-
|
|
99
|
+
if (params.get('saveData')) {
|
|
100
|
+
await SettingsManager.saveSettings(params); // saves token conditionally
|
|
101
|
+
}
|
|
98
102
|
|
|
99
103
|
return params;
|
|
100
104
|
}
|
package/lib/client/extend.js
CHANGED
|
@@ -71,7 +71,7 @@ module.exports = class Extend extends BaseCommand {
|
|
|
71
71
|
|
|
72
72
|
static async run(paramValues) {
|
|
73
73
|
try {
|
|
74
|
-
const params = await AuthManager.
|
|
74
|
+
const params = await AuthManager.login(paramValues);
|
|
75
75
|
|
|
76
76
|
if (process.env.DEBUG) {
|
|
77
77
|
Logger.log(`\n\nCreating extension project with parameters ${JSON.stringify({
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
const IP_ADDR = /^[1-9][0-9]{0,2}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/;
|
|
2
2
|
const schemaRegex = /^https?:\/\//;
|
|
3
|
-
const
|
|
3
|
+
const localhostRegex = /^(https?:\/\/)?(localhost|127\.0\.0\.1|\[?::1]?)\b/;
|
|
4
|
+
const httpSchema = 'http://';
|
|
5
|
+
const httpsSchema = 'https://';
|
|
4
6
|
|
|
5
7
|
function extractSubdomain(url) {
|
|
6
8
|
const hostname = new URL(url).hostname;
|
|
7
|
-
if (hostname
|
|
9
|
+
if (localhostRegex.test(hostname) || IP_ADDR.test(hostname)) {
|
|
8
10
|
return undefined;
|
|
9
11
|
}
|
|
10
12
|
return hostname.split('.')[0];
|
|
@@ -12,6 +14,8 @@ function extractSubdomain(url) {
|
|
|
12
14
|
|
|
13
15
|
module.exports = {
|
|
14
16
|
schemaRegex,
|
|
15
|
-
|
|
17
|
+
localhostRegex,
|
|
18
|
+
httpSchema,
|
|
19
|
+
httpsSchema,
|
|
16
20
|
extractSubdomain
|
|
17
21
|
};
|
package/lib/client/index.js
CHANGED
|
@@ -7,7 +7,7 @@ const { SettingsManager } = require('./settings_manager');
|
|
|
7
7
|
module.exports = {
|
|
8
8
|
extend: Extend.run,
|
|
9
9
|
activate: Activate.run,
|
|
10
|
-
login: AuthManager.
|
|
10
|
+
login: AuthManager.login,
|
|
11
11
|
logout: AuthManager.logout,
|
|
12
12
|
question: Question,
|
|
13
13
|
config: SettingsManager.config
|
package/lib/client/params.js
CHANGED
|
@@ -163,11 +163,13 @@ class BasicParams {
|
|
|
163
163
|
|
|
164
164
|
// - auth-related
|
|
165
165
|
this.passcode = new Param('passcode', '', { obfuscate: ObfuscationLevel.partial });
|
|
166
|
-
this.tokenStorage = new Param('tokenStorage',
|
|
166
|
+
this.tokenStorage = new Param('tokenStorage', undefined, { allowedValues: ['plain', 'keyring'] });
|
|
167
167
|
this.plain = new Param('plain', false, { internal: true }); // for backward compatibility - ignored
|
|
168
|
+
this.saveData = new Param('saveData', false, { internal: true });
|
|
168
169
|
this.renewLogin = new Param('renewLogin', false);
|
|
169
|
-
this.username = new Param('username', '');
|
|
170
|
+
this.username = new Param('username', '', { persist: Persistence.setting }); // only saved against localhost (non-productive); as setting due to ambiguous app URL
|
|
170
171
|
this.password = new Param('password', '', { obfuscate: ObfuscationLevel.full });
|
|
172
|
+
this.isEmptyPassword = new Param('isEmptyPassword', false, { internal: true, persist: Persistence.setting }); // extra param so we can ensure we never save a password
|
|
171
173
|
this.clientid = new Param('clientid', '');
|
|
172
174
|
this.clientsecret = new Param('clientsecret', '', { obfuscate: ObfuscationLevel.partial });
|
|
173
175
|
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const { join } = require('path');
|
|
3
|
+
const axios = require('axios');
|
|
4
|
+
|
|
5
|
+
const { unpackTarArchive } = require('@sap/cds/lib/utils/resources');
|
|
6
|
+
|
|
7
|
+
const { login } = require('./auth_manager');
|
|
8
|
+
const BaseCommand = require('./base_command');
|
|
9
|
+
const Logger = require('./helper/logging');
|
|
10
|
+
|
|
11
|
+
module.exports = class Pull extends BaseCommand {
|
|
12
|
+
|
|
13
|
+
static async run(paramValues) {
|
|
14
|
+
try {
|
|
15
|
+
const params = await login(paramValues);
|
|
16
|
+
|
|
17
|
+
Logger.log(`Pulling base model from ${params.get('appUrl')}, for subdomain '${params.get('subdomain')}', to project folder '${params.get('projectFolder')}'`);
|
|
18
|
+
|
|
19
|
+
const projectFolder = params.get('projectFolder');
|
|
20
|
+
const targetDir = join(projectFolder, 'node_modules', this.getAppPackageName(projectFolder));
|
|
21
|
+
fs.rmSync(targetDir, { force: true, recursive: true });
|
|
22
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
23
|
+
|
|
24
|
+
const tgzBuffer = Buffer.from(await this.getTgz(params));
|
|
25
|
+
return unpackTarArchive(tgzBuffer, targetDir, false);
|
|
26
|
+
|
|
27
|
+
} catch (mainError) {
|
|
28
|
+
Logger.error(undefined, mainError);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
static getAppPackageName(projectFolder) {
|
|
33
|
+
try {
|
|
34
|
+
return require(join(projectFolder, 'package.json')).cds.extends;
|
|
35
|
+
} catch (error) {
|
|
36
|
+
return '_base';
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
static async getTgz(params) {
|
|
41
|
+
const pullUrl = `${(params.get('appUrl'))}/-/cds/extensibility/pull`;
|
|
42
|
+
const options = { ...params.get('reqAuth'), responseType: 'arraybuffer' };
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
const response = await axios.post(pullUrl, {}, options);
|
|
46
|
+
return response.data;
|
|
47
|
+
} catch (error) {
|
|
48
|
+
return this.handleHttpError(error, params);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|