@sap/cds-dk 8.1.1 → 8.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/bin/bind.js +44 -11
- package/bin/cds-tsx.js +2 -0
- package/bin/cds.js +5 -3
- package/bin/compile/index.js +2 -1
- package/bin/deploy/index.js +19 -1
- package/bin/import.js +13 -4
- package/bin/init.js +1 -1
- package/bin/version.js +1 -0
- package/bin/watch.js +2 -2
- package/lib/bind/bindingManager.js +1 -1
- package/lib/bind/cfKeyProvider.js +1 -1
- package/lib/build/buildTaskProviderFactory.js +9 -3
- package/lib/build/plugins/helm/files/subcharts/content-deployment/Chart.yaml +1 -1
- package/lib/build/plugins/helm/files/subcharts/content-deployment/values.yaml +1 -1
- package/lib/build/plugins/helm/files/subcharts/service-instance/Chart.yaml +1 -1
- package/lib/build/plugins/helm/files/subcharts/service-instance/values.yaml +1 -1
- package/lib/build/plugins/helm/files/subcharts/web-application/Chart.yaml +1 -1
- package/lib/build/plugins/helm/files/subcharts/web-application/templates/deployment.yaml +2 -2
- package/lib/build/plugins/helm/files/subcharts/web-application/values.yaml +1 -1
- package/lib/build/provider/hana/2migration.js +6 -6
- package/lib/build/provider/nodejs/index.js +5 -4
- package/lib/build/util.js +2 -1
- package/lib/compile/to-mermaid.js +4 -6
- package/lib/import/common.js +16 -18
- package/lib/import/message.js +6 -5
- package/lib/import/odata/index.js +1 -1
- package/lib/import/odata/v2parser.js +18 -17
- package/lib/import/odata/v4parser.js +62 -62
- package/lib/init/constants.js +3 -2
- package/lib/init/mvn.js +43 -6
- package/lib/init/plugin.js +1 -1
- package/lib/init/projectReader.js +1 -1
- package/lib/init/template/approuter/files/containerize.yaml.hbs +5 -0
- package/lib/init/template/cloud-logging/files/mta.yaml.hbs +25 -0
- package/lib/init/template/cloud-logging/files/package.json +14 -0
- package/lib/init/template/cloud-logging/index.js +80 -0
- package/lib/init/template/containerize/files/containerize.yaml.hbs +5 -0
- package/lib/init/template/dynatrace/files/mta.yaml.hbs +24 -0
- package/lib/init/template/dynatrace/files/package.json.hbs +14 -0
- package/lib/init/template/dynatrace/files/sidecar.package.json +0 -0
- package/lib/init/template/dynatrace/index.js +55 -0
- package/lib/init/template/hana/files/containerize.yaml.hbs +5 -0
- package/lib/init/template/hana/files/package.json.hbs +5 -3
- package/lib/init/template/handler/index.js +22 -0
- package/lib/init/template/helm/index.js +5 -1
- package/lib/init/template/html5-repo/index.js +5 -0
- package/lib/init/template/http/index.js +1 -1
- package/lib/init/template/java/index.js +2 -2
- package/lib/init/template/multitenancy/files/containerize.yaml.hbs +5 -0
- package/lib/init/template/portal/files/portal-site/CommonDataModel.json.hbs +2 -2
- package/lib/init/template/portal/files/values.yaml.hbs +43 -0
- package/lib/init/template/portal/index.js +4 -2
- package/lib/init/template/telemetry/index.js +19 -0
- package/lib/init/template/typescript/files/package.json +1 -3
- package/lib/mtx/auth_manager.js +12 -15
- package/lib/mtx/settings_manager.js +5 -2
- package/lib/mtx/util/logging.js +4 -4
- package/lib/util/cf.js +15 -5
- package/lib/util/command.js +3 -3
- package/lib/watch/livereload-server.js +3 -3
- package/lib/watch/node-watch.js +3 -3
- package/npm-shrinkwrap.json +32 -23
- package/package.json +3 -2
- package/readme.md +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,51 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
|
7
7
|
|
|
8
8
|
The format is based on [Keep a Changelog](http://keepachangelog.com/).
|
|
9
9
|
|
|
10
|
+
## Version 8.2.0 - 2024-09-02
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `cds add dynatrace` adds configuration for Dynatrace.
|
|
15
|
+
- `cds add cloud-logging` adds configuration for SAP Cloud Logging. Option `--with-telemetry` allows for configuration with telemetry.
|
|
16
|
+
- `cds version` shows version information for `@cap-js/db-service`.
|
|
17
|
+
- `cds add portal` now adds portal configuration for Kyma.
|
|
18
|
+
- `cds add handler` allows to create handler stubs (for Java only, beta)
|
|
19
|
+
- `cds init --add java --no-db` lets you create a Java project without persistent database.
|
|
20
|
+
- `cds import` supports plugins.
|
|
21
|
+
- `cds add containerize` now supports unified-runtime.
|
|
22
|
+
- `cds add helm` now supports templating in the mountPath in the additionalVolumes.
|
|
23
|
+
- Experimental support for `tsx` through `cds-tsx`.
|
|
24
|
+
- `cds bind --to-app-services` now uses `vcap.name` to resolve multiple services with same type. A warning is issued in case of ambiguities.
|
|
25
|
+
- `cds compile --to ord -o <name>` supports `.json` file extension.
|
|
26
|
+
- `cds import --destination` applies destination credentials to existing service configurations.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- `cds add hana` writes configuration for `cds build/compile` to no longer produce native SAP HANA associations. This improves deployment performance, but has a one-time performance penalty (in the next deployment).
|
|
31
|
+
- `cds login` prints shorter messages about refresh tokens.
|
|
32
|
+
- `cds init` uses latest Maven Java archetype version 3.2.0 for creating Java projects.
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- `cds import` fix for single entity schema in OData V2.
|
|
37
|
+
- `cds add portal` correctly sets the `appId` in its `CommonDataModel.json` from the `manifest.json` app ID.
|
|
38
|
+
- `cds add html5-repo` adds the SAP BTP Destination service as a hard dependency again for Kyma projects.
|
|
39
|
+
- `cds build --ws-pack` correctly creates tarball archives for workspaces with nested `node_modules` folders.
|
|
40
|
+
- `cds import` now shows proper error message in case of bound action collision.
|
|
41
|
+
- `cds deploy --to hana` now runs an existing `hana` build task configuration instead of a default one.
|
|
42
|
+
|
|
43
|
+
### Removed
|
|
44
|
+
|
|
45
|
+
- Removed `build` and `build:ts` npm scripts that were generated into `package.json` when adding the `typescript` facet.
|
|
46
|
+
|
|
47
|
+
## Version 8.1.2 - 2024-08-17
|
|
48
|
+
|
|
49
|
+
### Fixed
|
|
50
|
+
|
|
51
|
+
- Dependency update for `axios` to fix CVE-2024-39338
|
|
52
|
+
- `cds login` now fetches the passcode URL for the subscriber tenant if the subdomain is given.
|
|
53
|
+
- `cds build` now correctly generates migration tables for `CodeList` entities.
|
|
54
|
+
|
|
10
55
|
## Version 8.1.1 - 2024-08-07
|
|
11
56
|
|
|
12
57
|
### Added
|
|
@@ -193,6 +238,19 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
|
|
|
193
238
|
|
|
194
239
|
- `cds add notebook` is removed. CAP Jupyter Notebooks have been replaced by custom CAP Notebooks for VS Code which are now part of the CDS Editor. See https://cap.cloud.sap/docs/tools/#add-cds-editor for more.
|
|
195
240
|
|
|
241
|
+
|
|
242
|
+
## Version 7.9.7 - 2024-08-22
|
|
243
|
+
|
|
244
|
+
### Fixed
|
|
245
|
+
|
|
246
|
+
- Dependency update for `axios` to fix CVE-2024-39338
|
|
247
|
+
- `cds build --for mtx-sidecar` now correctly supports different `srv` folder name.
|
|
248
|
+
- `cds build --ws-pack` correctly creates tarball archives for workspaces with nested `node_modules` folders.
|
|
249
|
+
- `cds version` now reports the correct version of `@sap/cds` if this one is installed locally along with a local `@sap/cds-dk` installation.
|
|
250
|
+
- `cds version -i` does not show a globally installed version when none is installed or linked.
|
|
251
|
+
- `cds version` reports correct `@sap/cds-compiler` version.
|
|
252
|
+
- `cds version` can skip over check for Java version
|
|
253
|
+
|
|
196
254
|
## Version 7.9.6 - 2024-07-19
|
|
197
255
|
|
|
198
256
|
### Fixed
|
package/bin/bind.js
CHANGED
|
@@ -110,6 +110,16 @@ async function cds_bind(args, options) {
|
|
|
110
110
|
throw `Option ${term.bold('--credentials')} requires a JSON object or a file path.`;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
if (!to && !app) {
|
|
114
|
+
// we currently don't support binding to a service without specifying the target instance
|
|
115
|
+
// const cds = require('../lib/cds');
|
|
116
|
+
// if (args[0] && cds.env.requires[args[0]]?.vcap?.name) {
|
|
117
|
+
// options.to = cds.env.requires[args[0]].vcap.name
|
|
118
|
+
// } else {
|
|
119
|
+
throw `Use option ${term.bold('--to')} or ${term.bold('-2')} to specify the target instance, e.g. ${term.bold('cds bind --to myInstance:myService')}`;
|
|
120
|
+
// }
|
|
121
|
+
}
|
|
122
|
+
|
|
113
123
|
// read credentials from file if it is a file, from JSON if it is JSON
|
|
114
124
|
if (credentials) {
|
|
115
125
|
let credentialsJson = options.credentials;
|
|
@@ -137,10 +147,6 @@ async function cds_bind(args, options) {
|
|
|
137
147
|
}
|
|
138
148
|
}
|
|
139
149
|
|
|
140
|
-
if (!to && !app) {
|
|
141
|
-
throw `Use option ${term.bold('--to')} or ${term.bold('-2')} to specify the target instance, e.g. ${term.bold('cds bind --to myInstance:myService')}`;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
150
|
if (app === true) {
|
|
145
151
|
throw `Option ${term.bold('--to-app-services')} requires an app name, for example ${term.bold('cds bind --to-app-services bookshop-srv')}.`
|
|
146
152
|
}
|
|
@@ -148,13 +154,40 @@ async function cds_bind(args, options) {
|
|
|
148
154
|
options.for ??= 'hybrid';
|
|
149
155
|
|
|
150
156
|
if (app) {
|
|
151
|
-
const
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
157
|
+
const cds = require('../lib/cds');
|
|
158
|
+
const resolvedServices = [], unresolvedServices = {}
|
|
159
|
+
const services = (await require('../lib/util/cf').getServices(app)).filter(s => Object.keys(s.credentials).length > 0)
|
|
160
|
+
|
|
161
|
+
services.forEach(service => {
|
|
162
|
+
const type = service.label || service.type;
|
|
163
|
+
const requiredServiceEntry = Object.entries(cds.env.requires).find(([, requiredService]) => requiredService.kind === type && requiredService?.vcap?.name === service.name)
|
|
164
|
+
if (requiredServiceEntry) {
|
|
165
|
+
resolvedServices.push({ options: { ...options, ...{ to: service.name, serviceArg: requiredServiceEntry[0] } } })
|
|
166
|
+
} else {
|
|
167
|
+
// check whether we can resolve this service
|
|
168
|
+
// multiple services of the same type cannot be resolved
|
|
169
|
+
if (services.some(s => (s.label || s.type) === type && s.name != service.name)) {
|
|
170
|
+
unresolvedServices[type] ??= [];
|
|
171
|
+
unresolvedServices[type].push(service);
|
|
172
|
+
} else {
|
|
173
|
+
resolvedServices.push({ options: { ...options, ...{ to: service.name } } })
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
const resolvedServiceBindings = (await Promise.all(resolvedServices.map(service => bind(service.options, service.options.to, out)))).flat();
|
|
179
|
+
|
|
180
|
+
if (resolvedServiceBindings.length > 0) {
|
|
181
|
+
await storeBindings(resolvedServiceBindings, options);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
Object.values(unresolvedServices)
|
|
185
|
+
.filter(services => services.length > 1)
|
|
186
|
+
.forEach(services => {
|
|
187
|
+
console.warn(`Found multiple service instances of the same type ${services[0].label || services[0].type}. This is not supported.`);
|
|
188
|
+
console.warn('Instead, bind each service individually, e.g.:');
|
|
189
|
+
services.forEach((service, idx) => console.warn(` cds bind <your local service name ${idx + 1}> --to ${service.name}`));
|
|
190
|
+
});
|
|
158
191
|
} else {
|
|
159
192
|
if (args.length > 1) {
|
|
160
193
|
throw 'Too many arguments: Please specify only one or no service.';
|
package/bin/cds-tsx.js
ADDED
package/bin/cds.js
CHANGED
|
@@ -215,9 +215,11 @@ function _require (id,o) {
|
|
|
215
215
|
return require (resolved)
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
218
|
+
const { sep } = require ('path')
|
|
219
|
+
if (process[Symbol.for('ts-node.register.instance')])
|
|
220
|
+
process.env.CDS_TYPESCRIPT = 'ts-node'
|
|
221
|
+
else if (process._preload_modules?.some(m => m?.includes(`${sep}tsx${sep}`)))
|
|
222
|
+
process.env.CDS_TYPESCRIPT = 'tsx'
|
|
221
223
|
|
|
222
224
|
module.exports = Object.assign ((..._) => cli.exec(..._), cli)
|
|
223
225
|
|
package/bin/compile/index.js
CHANGED
package/bin/deploy/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module.exports = Object.assign(deploy, {
|
|
2
2
|
options: ['--to', '--for', '--tunnel-address', '--vcap-file', '--delta-from' ],
|
|
3
|
-
flags: ['--no-save', '--auto-undeploy', '--dry', '--xdry', '--with-mocks', '--store-credentials', '--model-only', '--with-auto-schema-evolution' ],
|
|
3
|
+
flags: ['--no-save', '--auto-undeploy', '--dry', '--xdry', '--with-mocks', '--store-credentials', '--model-only', '--script', '--with-auto-schema-evolution' ],
|
|
4
4
|
shortcuts: ['-2', '-4'],
|
|
5
5
|
help: `
|
|
6
6
|
# SYNOPSIS
|
|
@@ -81,6 +81,12 @@ module.exports = Object.assign(deploy, {
|
|
|
81
81
|
*cds deploy --model-only --dry*. When used with *--dry* it writes the
|
|
82
82
|
generated SQL to stdout.
|
|
83
83
|
|
|
84
|
+
*--script
|
|
85
|
+
|
|
86
|
+
This is a schema evolution option to be used with --delta-from to generate
|
|
87
|
+
a script of SQL statements to then check and execute manually or for usage with tools such as LiquiBase.
|
|
88
|
+
This script might contain potentially lossy statements!
|
|
89
|
+
|
|
84
90
|
|
|
85
91
|
# EXAMPLES
|
|
86
92
|
cds deploy --to sqlite:db
|
|
@@ -127,7 +133,11 @@ async function deploy(_model, options) { // NOSONAR
|
|
|
127
133
|
}
|
|
128
134
|
}
|
|
129
135
|
try {
|
|
136
|
+
options.messages = []
|
|
137
|
+
if(options.script) options.dry = true // to ensure that we don't accidentally execute any SQLs
|
|
130
138
|
await deployer.deploy(_model, _db, options)
|
|
139
|
+
const log = this.log || _log
|
|
140
|
+
if (options.messages.length) log (options.messages, options)
|
|
131
141
|
} catch (e) {
|
|
132
142
|
if (e.code === 'MODEL_NOT_FOUND') {
|
|
133
143
|
if (!_model) throw new Error('No .cds models found, please specify one as an argument')
|
|
@@ -135,3 +145,11 @@ async function deploy(_model, options) { // NOSONAR
|
|
|
135
145
|
} else throw e
|
|
136
146
|
}
|
|
137
147
|
}
|
|
148
|
+
|
|
149
|
+
function _log (messages, options) {
|
|
150
|
+
const cds = require('../../lib/cds')
|
|
151
|
+
const { sortMessagesSeverityAware, deduplicateMessages } = cds.compiler
|
|
152
|
+
deduplicateMessages(messages)
|
|
153
|
+
messages = sortMessagesSeverityAware (messages)
|
|
154
|
+
cds._log (messages, options)
|
|
155
|
+
}
|
package/bin/import.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
module.exports = Object.assign(_import, {
|
|
2
2
|
_name: 'import',
|
|
3
|
-
options: ['--out', '--as', '--include-namespaces', '--from', '--config'],
|
|
3
|
+
options: ['--out', '--as', '--include-namespaces', '--from', '--config', '--destination'],
|
|
4
4
|
flags: ['--dry', '--force', '--no-copy', '--no-save', '--keep-namespace', '--beta'],
|
|
5
|
-
shortcuts: ['-o', '-as', '-ns', undefined, '-c', '-', '-f'],
|
|
5
|
+
shortcuts: ['-o', '-as', '-ns', undefined, '-c', undefined, '-', '-f'],
|
|
6
6
|
help: `
|
|
7
7
|
# SYNOPSIS
|
|
8
8
|
|
|
@@ -62,6 +62,9 @@ module.exports = Object.assign(_import, {
|
|
|
62
62
|
For OData V2 attributes with the namespace "sap" & "m" are captured by
|
|
63
63
|
default.
|
|
64
64
|
|
|
65
|
+
*--destination*
|
|
66
|
+
Destination name under which the remote service can be reached.
|
|
67
|
+
Not supported by import types "edmx", "openapi" or "asyncapi".
|
|
65
68
|
|
|
66
69
|
|
|
67
70
|
# EXAMPLES
|
|
@@ -75,7 +78,7 @@ module.exports = Object.assign(_import, {
|
|
|
75
78
|
cds import ~/Downloads/Petstore_OpenAPI.json --from openapi
|
|
76
79
|
cds import ~/Downloads/BookStore_AsyncAPI.json
|
|
77
80
|
cds import ~/Downloads/BookStore_AsyncAPI.json --from asyncapi
|
|
78
|
-
cds import ~/Downloads/API_BUSINESS_PARTNER.edmx -c {\\"[production]\\":{\\"credentials\\":{\\"destination\\":\\"UI3_noauth\\",\\"path\\":\\"/sap/cap/odata\\"}}}
|
|
81
|
+
cds import ~/Downloads/API_BUSINESS_PARTNER.edmx -c "{\\"[production]\\":{\\"credentials\\":{\\"destination\\":\\"UI3_noauth\\",\\"path\\":\\"/sap/cap/odata\\"}}}"
|
|
79
82
|
|
|
80
83
|
`})
|
|
81
84
|
const messages = require('../lib/import/message').getMessages();
|
|
@@ -93,10 +96,16 @@ async function _import(file, options = {}) {
|
|
|
93
96
|
await common.processOptions(options, apiOptions);
|
|
94
97
|
const srcFilePath = await common.preProcess(file, options, cwd);
|
|
95
98
|
|
|
99
|
+
const cds = require('../lib/cds')
|
|
100
|
+
await cds.plugins
|
|
101
|
+
|
|
96
102
|
// process - csn generation
|
|
97
103
|
// if --from option is given, call api directly accordingly
|
|
98
104
|
if (options.from) {
|
|
99
|
-
if (!cdsImport.import.from[options.from])
|
|
105
|
+
if (!cdsImport.import.from[options.from]) {
|
|
106
|
+
// the required plugin might not be installed, e.g. rfc importer
|
|
107
|
+
throw messages.UNSUPPORTED_FROM_OPTION;
|
|
108
|
+
}
|
|
100
109
|
csn = await cdsImport.import.from[options.from](srcFilePath, apiOptions);
|
|
101
110
|
} else {
|
|
102
111
|
csn = await cdsImport.import(srcFilePath, apiOptions);
|
package/bin/init.js
CHANGED
|
@@ -7,7 +7,7 @@ cds.root = join(process.cwd(), process.argv[3]?.startsWith('--') ? '.' : process
|
|
|
7
7
|
|
|
8
8
|
module.exports = Object.assign(init, {
|
|
9
9
|
handleCompletion,
|
|
10
|
-
options: ['--add', '--java:mvn', '--java:package', '--lint:custom', '--lint:custom:example'],
|
|
10
|
+
options: ['--add', '--java:mvn', '--java:package', '--lint:custom', '--lint:custom:example', '--no-db'],
|
|
11
11
|
shortcuts: ['-a'],
|
|
12
12
|
flags: ['--force', '--verbose'],
|
|
13
13
|
help: `
|
package/bin/version.js
CHANGED
|
@@ -75,6 +75,7 @@ function info({ root:cwd=process.cwd() }) {
|
|
|
75
75
|
..._versions_from(_pkg_path('@sap/cds-dk', cwd)), // local dk, important for Java projects
|
|
76
76
|
..._versions_from(_pkg_path('@sap/cds', __dirname)), // @sap/cds from here
|
|
77
77
|
..._versions_from(_pkg_path('@sap/cds', cds.home)), // ... or local @sap/cds
|
|
78
|
+
..._versions_from(_pkg_path('@cap-js/db-service', cwd)), // only required transitively
|
|
78
79
|
..._versions_from(cwd), // ... more from local app dependencies
|
|
79
80
|
'@sap/cds-compiler': cds.compiler.version(),
|
|
80
81
|
'Node.js': process.version,
|
package/bin/watch.js
CHANGED
|
@@ -49,7 +49,7 @@ module.exports = Object.assign ( watch, {
|
|
|
49
49
|
`})
|
|
50
50
|
|
|
51
51
|
const cds = require('../lib/cds')
|
|
52
|
-
const DEBUG = cds.
|
|
52
|
+
const DEBUG = cds.log('cli|watch')._debug
|
|
53
53
|
const {delimiter,dirname,relative,resolve,sep} = require ('path')
|
|
54
54
|
const {codes} = require('../lib/util/term'), t = codes
|
|
55
55
|
const fs = require ('fs')
|
|
@@ -90,7 +90,7 @@ async function watch ([cwd], {
|
|
|
90
90
|
_args: JSON.stringify(args),
|
|
91
91
|
_options: JSON.stringify(options)
|
|
92
92
|
})
|
|
93
|
-
if (process.env.CDS_TYPESCRIPT) {
|
|
93
|
+
if (process.env.CDS_TYPESCRIPT === 'ts-node' || process.env.CDS_TYPESCRIPT === 'true') {
|
|
94
94
|
// Needed by ts-node/tsc to find the tsconfig.json. Same as `--project`.
|
|
95
95
|
env.TS_NODE_PROJECT = env.TS_NODE_PROJECT ?? _cwd
|
|
96
96
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const bindingResolver = require('./bindingResolver')
|
|
2
2
|
const { logger } = require('./bindingUtil')
|
|
3
3
|
const cds = require('../cds')
|
|
4
|
-
const DEBUG = cds.
|
|
4
|
+
const DEBUG = cds.log('cli')._debug // REVISIT: This loads cds.env too early!
|
|
5
5
|
|
|
6
6
|
class BindingManager {
|
|
7
7
|
constructor(options = {}) {
|
|
@@ -4,7 +4,7 @@ const cds = require('../cds')
|
|
|
4
4
|
const { OUTPUT_MODE_FILESYSTEM, DEFAULT_SRC_FOLDER } = require('./constants')
|
|
5
5
|
const InternalBuildTaskProvider = require('./provider/internalBuildTaskProvider')
|
|
6
6
|
const BuildTaskProvider = require('./buildTaskProvider')
|
|
7
|
-
const { BuildError } = require('./util')
|
|
7
|
+
const { BuildError, normalizePath } = require('./util')
|
|
8
8
|
const DEBUG = cds.debug('cli|build')
|
|
9
9
|
|
|
10
10
|
class BuildTaskProviderFactory {
|
|
@@ -14,8 +14,14 @@ class BuildTaskProviderFactory {
|
|
|
14
14
|
options.clean = true
|
|
15
15
|
}
|
|
16
16
|
['for', 'src', 'dest'].forEach(key => {
|
|
17
|
-
if (options[key]
|
|
18
|
-
|
|
17
|
+
if (options[key]) {
|
|
18
|
+
if (typeof options[key] !== 'string') {
|
|
19
|
+
throw new BuildError(`Invalid build options - property '${key}' must be a string`)
|
|
20
|
+
}
|
|
21
|
+
if (key === 'src' || key === 'dest') {
|
|
22
|
+
// normalize path separator and remove trailing slash
|
|
23
|
+
options[key] = normalizePath(options[key])
|
|
24
|
+
}
|
|
19
25
|
}
|
|
20
26
|
})
|
|
21
27
|
this._context = { options, tasks: [] } // resolved tasks
|
|
@@ -83,7 +83,7 @@ spec:
|
|
|
83
83
|
mountPath: /bindings
|
|
84
84
|
{{- range $volume := .Values.additionalVolumes }}
|
|
85
85
|
- name: {{ $volume.name | quote }}
|
|
86
|
-
{{-
|
|
86
|
+
{{- tpl ($volume.volumeMount | toYaml) $ | nindent 10 }}
|
|
87
87
|
{{- end }}
|
|
88
88
|
{{- include "web-application.internal.serviceMounts" . | nindent 8 }}
|
|
89
89
|
resources:
|
|
@@ -136,7 +136,7 @@ spec:
|
|
|
136
136
|
mountPath: /bindings
|
|
137
137
|
{{- range $volume := $.Values.additionalVolumes }}
|
|
138
138
|
- name: {{ $volume.name | quote }}
|
|
139
|
-
{{-
|
|
139
|
+
{{- tpl ($volume.volumeMount | toYaml) $ | nindent 10 }}
|
|
140
140
|
{{- end }}
|
|
141
141
|
{{- include "web-application.internal.serviceMounts" $ | nindent 8 }}
|
|
142
142
|
{{- if $sidecar.resources }}
|
|
@@ -5,7 +5,7 @@ const { SEVERITY_WARNING } = require('../../constants')
|
|
|
5
5
|
const cds = require('../../../cds'), { compiler: cdsc } = cds
|
|
6
6
|
const cdscVersion = `-- generated by cds-compiler version ${cdsc.version()}`
|
|
7
7
|
const { getArtifactCdsPersistenceName } = cdsc
|
|
8
|
-
const DEBUG = cds.debug('cli|build')
|
|
8
|
+
const LOG = cds.log('cli|build'), DEBUG = cds.debug('cli|build')
|
|
9
9
|
|
|
10
10
|
module.exports = async (model, beforeImage, srcPath, options = {}) => {
|
|
11
11
|
const { definitions, migrations, afterImage, journalFileNames } = _compileToHana(model, options, beforeImage)
|
|
@@ -195,16 +195,16 @@ function _filterJournalArtifacts(afterImage) {
|
|
|
195
195
|
function _isPersistedAsJournalTable(artifact) {
|
|
196
196
|
return (
|
|
197
197
|
artifact.kind === 'entity' &&
|
|
198
|
-
artifact['@cds.persistence.journal'] &&
|
|
198
|
+
artifact['@cds.persistence.journal'] === true &&
|
|
199
199
|
!artifact.abstract &&
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
(
|
|
200
|
+
artifact['@cds.persistence.skip'] !== true && // might have value 'if-unused'
|
|
201
|
+
artifact['@cds.persistence.exists'] !== true &&
|
|
202
|
+
(!artifact.query && !artifact.projection || artifact['@cds.persistence.table'] === true)
|
|
203
203
|
)
|
|
204
204
|
}
|
|
205
205
|
|
|
206
206
|
function _debug(definitions, migrations, journalFileNames) {
|
|
207
|
-
if (
|
|
207
|
+
if (LOG._debug) {
|
|
208
208
|
DEBUG('compile.to.hana returned')
|
|
209
209
|
for (const { name, suffix, sql } of definitions) {
|
|
210
210
|
if (suffix === '.hdbtable' && journalFileNames.has(name)) {
|
|
@@ -5,10 +5,10 @@ const cmd = require('../../../util/command');
|
|
|
5
5
|
const EdmxBuildPlugin = require('../edmxBuildPlugin')
|
|
6
6
|
const { BuildError, getWorkspaces } = require('../../util')
|
|
7
7
|
const { OUTPUT_MODE, OUTPUT_MODE_FILESYSTEM, ODATA_VERSION_V2, FOLDER_GEN, CONTENT_EDMX, CONTENT_PACKAGELOCK_JSON,
|
|
8
|
-
CONTENT_NPMRC, CONTENT_CDSRC_JSON, CONTENT_ENV, CONTENT_DEFAULT_ENV_JSON, FLAVOR_LOCALIZED_EDMX,
|
|
8
|
+
CONTENT_NPMRC, CONTENT_CDSRC_JSON, CONTENT_ENV, CONTENT_DEFAULT_ENV_JSON, FLAVOR_LOCALIZED_EDMX,
|
|
9
9
|
OPTION_WS_PACK} = require('../../constants')
|
|
10
10
|
const { WARNING } = EdmxBuildPlugin
|
|
11
|
-
const DEBUG = cds.debug('cli|build')
|
|
11
|
+
const LOG = cds.log('cli|build'), DEBUG = cds.debug('cli|build')
|
|
12
12
|
|
|
13
13
|
class NodejsBuildPlugin extends EdmxBuildPlugin {
|
|
14
14
|
init() {
|
|
@@ -166,6 +166,7 @@ class NodejsBuildPlugin extends EdmxBuildPlugin {
|
|
|
166
166
|
if (this.task.options.workspaces) {
|
|
167
167
|
workspaces = Array.isArray(this.task.options.workspaces) ? this.task.options.workspaces : [this.task.options.workspaces]
|
|
168
168
|
} else {
|
|
169
|
+
// devDependencies are not considered
|
|
169
170
|
workspaces = await getWorkspaces(true, false, wsRoot);
|
|
170
171
|
}
|
|
171
172
|
if (workspaces.length) {
|
|
@@ -204,7 +205,7 @@ class NodejsBuildPlugin extends EdmxBuildPlugin {
|
|
|
204
205
|
} catch (err) {
|
|
205
206
|
// ignore
|
|
206
207
|
}
|
|
207
|
-
if (fs.existsSync(path.join(dir, '.gitmodules'))
|
|
208
|
+
if (fs.existsSync(path.join(dir, '.gitmodules'))) {
|
|
208
209
|
return // project root reached
|
|
209
210
|
}
|
|
210
211
|
if (path.dirname(dir) !== dir) {
|
|
@@ -217,7 +218,7 @@ class NodejsBuildPlugin extends EdmxBuildPlugin {
|
|
|
217
218
|
workspaces.forEach(w => args.push(`-w=${w}`))
|
|
218
219
|
|
|
219
220
|
DEBUG?.(`execute command: npm ${args.join(', ')}`)
|
|
220
|
-
const result = await cmd.spawnCommand('npm', args, { cwd: wsRoot }, true, !!
|
|
221
|
+
const result = await cmd.spawnCommand('npm', args, { cwd: wsRoot }, true, !!LOG._debug)
|
|
221
222
|
DEBUG?.(result)
|
|
222
223
|
return JSON.parse(result)
|
|
223
224
|
}
|
package/lib/build/util.js
CHANGED
|
@@ -190,7 +190,8 @@ async function getWorkspaces(resolve = false, devDependencies = true, wsRoot = c
|
|
|
190
190
|
// read npm workspaces
|
|
191
191
|
const pkgs = await _execNpmWs(wsRoot)
|
|
192
192
|
pkgs.forEach(pkg => {
|
|
193
|
-
|
|
193
|
+
// only create tarball archives for dependencies with version '*'
|
|
194
|
+
if (!resolve || devDependencies && pgkJson.devDependencies?.[pkg] === '*' || pgkJson.dependencies?.[pkg] === '*') {
|
|
194
195
|
const workspace = _getWorkspace(wsRoot, pkg)
|
|
195
196
|
if (workspace) {
|
|
196
197
|
workspaces.push(workspace)
|
|
@@ -35,12 +35,10 @@ module.exports = function to_mermaid (model, options={}) {
|
|
|
35
35
|
.filter (srv => !srvFilter || srv.name === srvFilter)
|
|
36
36
|
.forEach(srv => {
|
|
37
37
|
namespaces[srv.name] = []
|
|
38
|
-
model.entities(srv)
|
|
39
|
-
.filter (entityFilter)
|
|
40
|
-
.forEach (e => {
|
|
38
|
+
for (let e of model.entities(srv)) if (entityFilter(e)) {
|
|
41
39
|
namespaces[srv.name].push(e)
|
|
42
40
|
seenEntities.add(e.name)
|
|
43
|
-
}
|
|
41
|
+
}
|
|
44
42
|
})
|
|
45
43
|
|
|
46
44
|
// group other namespaces/services
|
|
@@ -69,7 +67,7 @@ module.exports = function to_mermaid (model, options={}) {
|
|
|
69
67
|
diag += `["${simpleName}"]` // simple name as label
|
|
70
68
|
if (elemOpts) {
|
|
71
69
|
diag += ` {\n`
|
|
72
|
-
e.elements
|
|
70
|
+
if (e.elements) [...e.elements].forEach (el => {
|
|
73
71
|
if ((elemOpts === 'all' || elemOpts === true) || (el.key && elemOpts == 'keys')) {
|
|
74
72
|
diag += ` +${el._type?.replace('cds.','')} ${el.name}`
|
|
75
73
|
diag += `\n`
|
|
@@ -90,7 +88,7 @@ module.exports = function to_mermaid (model, options={}) {
|
|
|
90
88
|
: model.all('entity').filter (entityFilter) // if no grouping and no service filter is on
|
|
91
89
|
entities.forEach(e => {
|
|
92
90
|
if (!diag.length) diag = `classDiagram\n${direction}`
|
|
93
|
-
e.elements
|
|
91
|
+
if (e.elements) [...e.elements].forEach (el => {
|
|
94
92
|
if (el instanceof cds.Association) {
|
|
95
93
|
if (el.target.endsWith('.texts')) return
|
|
96
94
|
const type = el.type === 'cds.Composition' ? '*-->' : '-->'
|
package/lib/import/common.js
CHANGED
|
@@ -239,7 +239,7 @@ async function _generateChecksumValidate(dest, output, force) {
|
|
|
239
239
|
}
|
|
240
240
|
}
|
|
241
241
|
|
|
242
|
-
// if force flag
|
|
242
|
+
// if force flag enabled
|
|
243
243
|
if (force) {
|
|
244
244
|
// current and existing file content are same, and the existing
|
|
245
245
|
// checksum is not modified, then return the existing file content
|
|
@@ -296,12 +296,12 @@ async function _getResult(output, as, dest, force, kind) {
|
|
|
296
296
|
}
|
|
297
297
|
|
|
298
298
|
async function _write(result, service, cwd) {
|
|
299
|
-
let dest, output, using, message,
|
|
299
|
+
let dest, output, using, message, extension;
|
|
300
300
|
output = result[0];
|
|
301
301
|
dest = result[1];
|
|
302
302
|
await write(dest, output, "utf-8");
|
|
303
|
-
|
|
304
|
-
dest = dest.replace(
|
|
303
|
+
extension = dest.substring(dest.lastIndexOf('.'));
|
|
304
|
+
dest = dest.replace(extension, '');
|
|
305
305
|
if (service.length > 1){
|
|
306
306
|
using = `using { ${service.join(', ')}} from './${path.relative('srv', dest).replace(/\\/g, '/')}'`;
|
|
307
307
|
}
|
|
@@ -327,13 +327,11 @@ async function _updatePackageJson(dest, services, kind, cwd, config) {
|
|
|
327
327
|
}
|
|
328
328
|
let package_json_updated = false;
|
|
329
329
|
for (let service of services) {
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
package_json_updated = true;
|
|
336
|
-
}
|
|
330
|
+
// always update from given config data - e.g. delta imports may want to add service configuration data
|
|
331
|
+
const model = path.relative(cwd, dest).replace(/\\/g, '/'); // cds env must not be platform specific
|
|
332
|
+
cds.env.requires[service] = requires[service] = { kind: kind, model, ...config };
|
|
333
|
+
await write(package_json, JSON.stringify(conf, null, ' '));
|
|
334
|
+
package_json_updated = true;
|
|
337
335
|
}
|
|
338
336
|
if (package_json_updated) {
|
|
339
337
|
console.log(`[cds] - updated ./package.json`);
|
|
@@ -353,6 +351,13 @@ function _parseValidJsonConfig(config) {
|
|
|
353
351
|
async function postProcess(filePath, options, csn, cwd) {
|
|
354
352
|
const services = _getServiceNames(csn);
|
|
355
353
|
let config = _parseValidJsonConfig(options.config);
|
|
354
|
+
|
|
355
|
+
// add destination configuration
|
|
356
|
+
if (options.destination) {
|
|
357
|
+
config ??= {};
|
|
358
|
+
config.credentials = { destination: options.destination };
|
|
359
|
+
}
|
|
360
|
+
|
|
356
361
|
const external = path.resolve(cwd, 'srv/external');
|
|
357
362
|
const destFilePath = path.join(external, path.basename(filePath));
|
|
358
363
|
if (options.out) options.out = _validateAndComputeOutputFilePath(options.out, options.as, destFilePath);
|
|
@@ -385,13 +390,6 @@ async function identifyFile(filepath) {
|
|
|
385
390
|
return extension;
|
|
386
391
|
}
|
|
387
392
|
|
|
388
|
-
function isLinux() {
|
|
389
|
-
let platform = process.platform;
|
|
390
|
-
if (platform === 'linux' || platform === 'win32') {
|
|
391
|
-
return true;
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
|
|
395
393
|
function readEnvVariables(options, cliCheck) {
|
|
396
394
|
if (cds.env.import) {
|
|
397
395
|
if (cliCheck) {
|
package/lib/import/message.js
CHANGED
|
@@ -12,6 +12,7 @@ const messages = {
|
|
|
12
12
|
FILE_MODIFIED: 'The file with the same name exists and is been modified. Use --force flag to forcefully overwrite the file.',
|
|
13
13
|
OUTPUT_FILE_MISMATCH: 'Specify the file extension that --as option supports.',
|
|
14
14
|
INVALID_AS_OPTION: 'For --as option, please specify one of these output file format [cds, csn, json].',
|
|
15
|
+
UNSUPPORTED_FROM_OPTION: 'For --from option, please specify one of these types [edmx, openapi, asyncapi, rfc]. Make sure the required importer plugin is installed.',
|
|
15
16
|
INCORRECT_EXTENSION: 'If --as option is not provided, then please provide either .json or .csn output file extension.',
|
|
16
17
|
INCORRECT_INPUT_NAMESPACES: 'Invalid value for --include-namespaces option. Specify namespaces as comma-separated list or "*"',
|
|
17
18
|
MISSING_ASSOCIATION: 'Association is missing in the input file provided. Please check the edmx file.',
|
|
@@ -22,14 +23,14 @@ const messages = {
|
|
|
22
23
|
UNRESOLVED_TYPE: 'Could not resolve the type: ',
|
|
23
24
|
NO_RETURN_TYPE: 'No ReturnType found in Function: ',
|
|
24
25
|
INVALID_ENUM_TYPE: 'The Underlying type provided is not supported for the EnumType: ',
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
INVALID_BOUND_PARAM_TYPE: 'Parameter Type of Bound Action/Function should not refer to an Entity in another Schema.',
|
|
27
|
+
UNBOUND_ACTION_COLLISION: 'Unbound Action does not support collision. Check the Action ',
|
|
28
|
+
BOUND_ACTION_COLLISION: 'The combination of Action name and binding parameter type must be unique for Bound Action ',
|
|
28
29
|
STREAM_NO_COLLECTION: `'Edm.Stream' cannot be of Collection type.`,
|
|
29
30
|
UNSUPPORTED_PROPERTY_TYPE: 'Property cannot be of EntityType. Check the type: ',
|
|
30
|
-
|
|
31
|
+
UNRESOLVED_SCHEMA_NAMESPACE: `Could not resolve the schema `,
|
|
31
32
|
INVALID_DATATYPE: `Invalid Data Type `,
|
|
32
|
-
ELEMENT_NAME_COLLISION: 'Collision between EntityContainer Element Name and Schema Element Name is
|
|
33
|
+
ELEMENT_NAME_COLLISION: 'Collision between EntityContainer Element Name and Schema Element Name is currently not supported. Please check the element name: ',
|
|
33
34
|
NO_DEFAULT_FOR_COLLECTIONS: 'WARNING: Collection type cannot have a Default value.',
|
|
34
35
|
BINARY_MAXLENGTH: 'WARNING: MaxLength for type Edm.Binary should not exceed 5000.',
|
|
35
36
|
SCALE_GT_PRECISION: 'WARNING: Scale value should not be greater than Precision value.',
|