@sap/cds-dk 9.0.6 → 9.1.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 +26 -0
- package/bin/add.js +9 -6
- package/bin/debug.js +14 -7
- package/bin/repl.js +9 -2
- package/bin/up.js +16 -6
- package/lib/build/provider/fiori/index.js +2 -4
- package/lib/init/constants.js +11 -10
- package/lib/init/index.js +32 -4
- package/lib/init/merge.js +4 -1
- package/lib/init/plugin.js +0 -33
- package/lib/init/projectReader.js +1 -1
- package/lib/init/template/ams/files/Chart.yaml.hbs +3 -1
- package/lib/init/template/approuter/files/mta.yaml.hbs +2 -1
- package/lib/init/template/cloud-logging/files/java-cdsrc.json.hbs +6 -0
- package/lib/init/template/cloud-logging/files/package.json.hbs +7 -0
- package/lib/init/template/cloud-logging/index.js +9 -10
- package/lib/init/template/containerize/index.js +1 -1
- package/lib/init/template/data/as-json.js +3 -3
- package/lib/init/template/hana/index.js +3 -2
- package/lib/init/template/handler/files/extension/package.json +1 -1
- package/lib/init/template/html5-repo/files/mta.yaml.hbs +3 -1
- package/lib/init/template/html5-repo/index.js +1 -1
- package/lib/init/template/http/index.js +55 -53
- package/lib/init/template/ias/files/Chart.yaml.hbs +3 -1
- package/lib/init/template/ias/files/mta.yaml.hbs +2 -2
- package/lib/init/template/ias/index.js +3 -4
- package/lib/init/template/mta/index.js +5 -5
- package/lib/init/template/multitenancy/index.js +3 -4
- package/lib/init/template/nodejs/files/package.json.hbs +1 -1
- package/lib/init/template/portal/index.js +1 -1
- package/lib/init/template/test/files/package.json +8 -0
- package/lib/init/template/test/files/test/test.xs.hbs +36 -0
- package/lib/init/template/test/index.js +152 -0
- package/lib/init/template/typescript/files/package.json +1 -1
- package/lib/init/template/xsuaa/index.js +2 -2
- package/lib/lint/Linter.js +1 -4
- package/lib/lint/eslintHelp.json +84 -0
- package/lib/mtx/auth_manager.js +0 -2
- package/lib/util/axios.js +77 -31
- package/npm-shrinkwrap.json +14 -14
- package/package.json +1 -1
- package/lib/init/template/cloud-logging/files/java-cdsrc.json +0 -5
- package/lib/lint/generators.js +0 -103
package/CHANGELOG.md
CHANGED
|
@@ -6,11 +6,37 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
6
6
|
|
|
7
7
|
The format is based on [Keep a Changelog](https://keepachangelog.com/).
|
|
8
8
|
|
|
9
|
+
## Version 9.1.0 - 2025-07-02
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `cds add test` to generate test files for CDS services [experimental]
|
|
14
|
+
- `cds debug --no-devtools` allows to skip opening the developer tools.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- `cds add helm` doesn't route the subscription callbacks through the app router any longer.
|
|
19
|
+
- `cds lint` now uses local copy of `eslint` help content.
|
|
20
|
+
- `cds add cloud-logging` will correctly add the Helm dependency to `Chart.yaml`.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- `cds add hana` for Java correctly adds the HANA dependencies to `chart/Chart.yaml`.
|
|
25
|
+
- `cds add xsuaa` for Java doesn't throw an error when the `.cdsrc.json` is not existing.
|
|
26
|
+
- `cds build --for fiori` stores EDMX files again relative if `dataSources.mainService.settings.localUri` in UI5's `manifest.json` is a relative path.
|
|
27
|
+
- `cds add ams/ias` add the `repository` in combination with `cds add helm-unified-runtime`.
|
|
28
|
+
- `cds add xsuaa` adds a wildcard prefix to the domain name to allow for multitenancy use cases.
|
|
29
|
+
- `cds add portal` for Java binds the HTML5 repo runtime and portal service to the Java server instead of the MTX sidecar, to allow for CAP Java built-in dependencies resolution.
|
|
30
|
+
- `cds repl --run` can now run again w/o `@cap-js/cds-test` installed.
|
|
31
|
+
- `cds push` and other commands now handle request errors more robustly
|
|
32
|
+
- `cds debug` now also honors the `--host` parameter when it starts `cds watch`.
|
|
33
|
+
|
|
9
34
|
## Version 9.0.6 - 2025-06-18
|
|
10
35
|
|
|
11
36
|
### Changed
|
|
12
37
|
|
|
13
38
|
- `cds build` now adds an `engines.node = ">=20"` entry to the effective _package.json_ iff it is missing from the project's _package.json_ to avoid engine confusion when deploying to Cloud Foundry
|
|
39
|
+
- `cds add` without any flag now shows the help (`cds add --help`) instead of throwing an error
|
|
14
40
|
|
|
15
41
|
## Version 9.0.5 - 2025-06-06
|
|
16
42
|
|
package/bin/add.js
CHANGED
|
@@ -65,17 +65,20 @@ ${Object.entries(conf).sort(([a], [b]) => a.localeCompare(b)).flatMap(([pluginNa
|
|
|
65
65
|
|
|
66
66
|
# EXAMPLES
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
68
|
+
*cds add* sample
|
|
69
|
+
*cds add* multitenancy,hana,xsuaa
|
|
70
|
+
*cds add* data --filter my.namespace.MyEntity
|
|
71
|
+
*cds add* mta
|
|
72
|
+
*cds add* helm
|
|
74
73
|
|
|
75
74
|
# SEE ALSO
|
|
76
75
|
|
|
77
76
|
*cds init*
|
|
78
77
|
|
|
78
|
+
# SUMMARY
|
|
79
|
+
|
|
80
|
+
*cds add* <feature | comma-separated list of features>
|
|
81
|
+
|
|
79
82
|
`});
|
|
80
83
|
|
|
81
84
|
async function handleCompletion(currentWord, previousWord, argv, util) {
|
package/bin/debug.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module.exports = Object.assign(debug, {
|
|
2
|
-
options: ['--port', '--host', '--force'],
|
|
2
|
+
options: ['--port', '--host', '--force', '--no-devtools'],
|
|
3
3
|
shortcuts: ['-p', '-h', '-f'],
|
|
4
4
|
flags: [/*'--vscode', '--k8s'*/],
|
|
5
5
|
help: `
|
|
@@ -14,6 +14,7 @@ module.exports = Object.assign(debug, {
|
|
|
14
14
|
If <app> is given, it's assumed to be running on the currently logged-in
|
|
15
15
|
Cloud Foundry space (check with 'cf target').
|
|
16
16
|
SSH access to the app is required (check with 'cf ssh-enabled').
|
|
17
|
+
Chrome DevTools are opened automatically for Node.js applications.
|
|
17
18
|
|
|
18
19
|
If no <app> is given, the app in the current working directory is started
|
|
19
20
|
(with 'cds watch --debug' for Node.js and 'mvn spring-boot:run' for Java).
|
|
@@ -28,6 +29,10 @@ module.exports = Object.assign(debug, {
|
|
|
28
29
|
|
|
29
30
|
the debug port (default: '9229' for Node.js, '8000' for Java)
|
|
30
31
|
|
|
32
|
+
*--no-devtools*
|
|
33
|
+
|
|
34
|
+
don't open developer tools automatically
|
|
35
|
+
|
|
31
36
|
*-f* | *--force*
|
|
32
37
|
|
|
33
38
|
if necessary, automatically enable ssh for the app and restart it
|
|
@@ -36,6 +41,7 @@ module.exports = Object.assign(debug, {
|
|
|
36
41
|
|
|
37
42
|
*cds debug*
|
|
38
43
|
*cds debug* bookshop-srv --port 8001
|
|
44
|
+
*cds debug* bookshop-srv --host 0.0.0.0
|
|
39
45
|
`})
|
|
40
46
|
|
|
41
47
|
async function debug() {
|
|
@@ -45,7 +51,7 @@ async function debug() {
|
|
|
45
51
|
const DEBUG = /\b(y|all|debug)\b/.test(process.env.DEBUG) ? console.debug : undefined
|
|
46
52
|
|
|
47
53
|
const [appName] = cds.cli.argv
|
|
48
|
-
const { port, host = '127.0.0.1', vscode, force } = cds.cli.options
|
|
54
|
+
const { port = 9229, host = '127.0.0.1', vscode, force } = cds.cli.options
|
|
49
55
|
|
|
50
56
|
const maxAttempts = 15
|
|
51
57
|
let attempts = 0
|
|
@@ -60,8 +66,9 @@ async function debug() {
|
|
|
60
66
|
}
|
|
61
67
|
else {
|
|
62
68
|
const script = process.argv[1] // `.../cds` or `.../cds-tsx`
|
|
63
|
-
|
|
64
|
-
|
|
69
|
+
const hostport = `${host}:${port}`
|
|
70
|
+
console.log(`Starting '${cds.utils.path.basename(script)} watch --debug ${(host != '127.0.0.1' || port != 9229) ? hostport : ''}'`)
|
|
71
|
+
fork(script, ['watch', '--debug', hostport]).on('error', e => { throw 'Failed to start debug process:' + e.message })
|
|
65
72
|
}
|
|
66
73
|
}
|
|
67
74
|
else if (cds.cli.options.k8s) { // Kyma/Kubernetes
|
|
@@ -74,7 +81,7 @@ async function debug() {
|
|
|
74
81
|
if (kind === 'node') {
|
|
75
82
|
enableNodeDebugging(pid, appName)
|
|
76
83
|
const portLocal = openTunnel(9229)
|
|
77
|
-
openDevTools(portLocal)
|
|
84
|
+
if (!cds.cli.options['no-devtools']) openDevTools(portLocal)
|
|
78
85
|
}
|
|
79
86
|
else if (kind === 'java') {
|
|
80
87
|
const portRemote = findJavaDebugPort(pid, appName)
|
|
@@ -114,8 +121,8 @@ async function debug() {
|
|
|
114
121
|
|
|
115
122
|
function openTunnel(portRemote) {
|
|
116
123
|
const portLocal = port || portRemote
|
|
117
|
-
console.log(`\nOpening SSH tunnel on ${portRemote}:${host}:${portLocal}`)
|
|
118
|
-
spawn('cf', ['ssh', '-N', '-L', `${portRemote}:${host}:${portLocal}`, appName], { stdio: 'inherit' })
|
|
124
|
+
console.log(`\nOpening SSH tunnel on ${host}:${portRemote}:${host}:${portLocal}`)
|
|
125
|
+
spawn('cf', ['ssh', '-N', '-L', `${host}:${portRemote}:${host}:${portLocal}`, appName], { stdio: 'inherit' })
|
|
119
126
|
return portLocal
|
|
120
127
|
}
|
|
121
128
|
|
package/bin/repl.js
CHANGED
|
@@ -28,7 +28,7 @@ module.exports = Object.assign (repl, {
|
|
|
28
28
|
|
|
29
29
|
*cds repl* --run bookshop
|
|
30
30
|
*cds repl* --run .
|
|
31
|
-
*cds repl* --use
|
|
31
|
+
*cds repl* --use ql
|
|
32
32
|
|
|
33
33
|
# SEE ALSO
|
|
34
34
|
|
|
@@ -92,7 +92,14 @@ async function repl (_, options={}) {
|
|
|
92
92
|
process.on = (event, listener) => event !== 'uncaughtException' && event !== 'unhandledRejection' && process.addListener(event, listener)
|
|
93
93
|
|
|
94
94
|
async function _run (project) {
|
|
95
|
-
|
|
95
|
+
try {
|
|
96
|
+
if (require.resolve('@cap-js/cds-test', {paths: [cds.root, cds.home]})) {
|
|
97
|
+
await cds.test (project)
|
|
98
|
+
}
|
|
99
|
+
} catch (e) {
|
|
100
|
+
if (e.code !== 'MODULE_NOT_FOUND') throw e
|
|
101
|
+
await cds.exec ('--project', project, '--port', '0', '--in-memory?')
|
|
102
|
+
}
|
|
96
103
|
_export ('entities', 'services')
|
|
97
104
|
}
|
|
98
105
|
|
package/bin/up.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module.exports = Object.assign(up, {
|
|
2
|
-
options: ['--to'],
|
|
3
|
-
shortcuts: ['-2'],
|
|
2
|
+
options: ['--to', '--namespace'],
|
|
3
|
+
shortcuts: ['-2', '-n'],
|
|
4
4
|
flags: [],
|
|
5
5
|
help: `
|
|
6
6
|
# SYNOPSIS
|
|
@@ -15,10 +15,16 @@ module.exports = Object.assign(up, {
|
|
|
15
15
|
|
|
16
16
|
The platform to deploy to. Default is 'cf'.
|
|
17
17
|
|
|
18
|
+
*-n* | *--namespace* <name>
|
|
19
|
+
|
|
20
|
+
(Kubernetes only) Target namespace. If it does not yet exist it will be
|
|
21
|
+
created automatically via *helm --create-namespace*.
|
|
22
|
+
|
|
18
23
|
# EXAMPLES
|
|
19
24
|
|
|
20
25
|
*cds up*
|
|
21
26
|
*cds up --to k8s*
|
|
27
|
+
*cds up --to k8s --namespace e2e-tests*
|
|
22
28
|
`})
|
|
23
29
|
|
|
24
30
|
const { execSync, spawn } = require('node:child_process')
|
|
@@ -95,14 +101,18 @@ async function up() {
|
|
|
95
101
|
}
|
|
96
102
|
|
|
97
103
|
if (cds.cli.options.to === 'k8s') {
|
|
104
|
+
const ns = cds.cli.options.namespace
|
|
105
|
+
const nsHelm = ns ? `--namespace ${ns} --create-namespace` : ''
|
|
106
|
+
const nsKubectl = ns ? `-n ${ns}` : ''
|
|
107
|
+
|
|
98
108
|
run('npm i --package-lock')
|
|
99
109
|
await runDetectingError('ctz containerize.yaml --log --push', /^\[?ERROR\]?.*/m)
|
|
100
|
-
let helmUpgrade = `helm upgrade --install ${appName} ./gen/chart --wait --wait-for-jobs`
|
|
110
|
+
let helmUpgrade = `helm upgrade --install ${appName} ./gen/chart ${nsHelm} --wait --wait-for-jobs`
|
|
101
111
|
if (hasXsuaa) helmUpgrade += ' --set-file xsuaa.jsonParameters=xs-security.json'
|
|
102
112
|
run(helmUpgrade)
|
|
103
|
-
run(`kubectl rollout status deployment ${appName}-srv --timeout=8m`)
|
|
104
|
-
if (hasApprouter) run(`kubectl rollout status deployment ${appName}-approuter --timeout=8m`)
|
|
105
|
-
if (exists('mtx/sidecar')) run(`kubectl rollout status deployment ${appName}-sidecar --timeout=8m`)
|
|
113
|
+
run(`kubectl rollout status deployment ${appName}-srv ${nsKubectl} --timeout=8m`)
|
|
114
|
+
if (hasApprouter) run(`kubectl rollout status deployment ${appName}-approuter ${nsKubectl} --timeout=8m`)
|
|
115
|
+
if (exists('mtx/sidecar')) run(`kubectl rollout status deployment ${appName}-sidecar ${nsKubectl} --timeout=8m`)
|
|
106
116
|
} else {
|
|
107
117
|
run('mbt build -t gen --mtar mta.tar')
|
|
108
118
|
run('cf deploy gen/mta.tar -f')
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const path = require('path')
|
|
2
2
|
const cds = require('../../../cds')
|
|
3
3
|
const EdmxBuildPlugin = require('../edmxBuildPlugin')
|
|
4
|
-
const { URL } = require('node:url')
|
|
5
4
|
const { getProperty, relativePaths } = require('../../util')
|
|
6
5
|
const { OUTPUT_MODE, OUTPUT_MODE_RESULT, BUILD_TASK_FIORI, CDS_CONFIG_PATH_SEP, OUTPUT_MODE_FILESYSTEM } = require('../../constants')
|
|
7
6
|
const DEBUG = cds.debug('cli|build')
|
|
@@ -9,7 +8,7 @@ const DEBUG = cds.debug('cli|build')
|
|
|
9
8
|
/**
|
|
10
9
|
* With cds 4 service metadata for the UI service binding is no longer created by default.
|
|
11
10
|
* For SAP Web IDE Full-Stack compatibility a corresponding metadata.xml is still generated.
|
|
12
|
-
* Though, 'fiori' build tasks can still be configured for UI5 mock server usage - see
|
|
11
|
+
* Though, 'fiori' build tasks can still be configured for UI5 mock server usage - see cap/issues#8673
|
|
13
12
|
*/
|
|
14
13
|
class FioriBuildPlugin extends EdmxBuildPlugin {
|
|
15
14
|
init() {
|
|
@@ -159,8 +158,7 @@ class FioriBuildPlugin extends EdmxBuildPlugin {
|
|
|
159
158
|
}
|
|
160
159
|
|
|
161
160
|
_strippedUrlPath(urlString) {
|
|
162
|
-
|
|
163
|
-
return url.pathname.replace(/^(\/|\\)/, '').replace(/(\/|\\)$/, '') // strip leading and trailing slash or backslash
|
|
161
|
+
return urlString.replace(/^(\/|\\)/, '').replace(/(\/|\\)$/, '') // strip leading and trailing slash or backslash
|
|
164
162
|
}
|
|
165
163
|
}
|
|
166
164
|
|
package/lib/init/constants.js
CHANGED
|
@@ -17,29 +17,30 @@ module.exports = {
|
|
|
17
17
|
TYPER: 'typer',
|
|
18
18
|
TYPESCRIPT: 'typescript', // must run before SAMPLE, as that influences whether .js or .ts files are created
|
|
19
19
|
EXTENSION: 'extension',
|
|
20
|
-
SAMPLES: 'samples', // deprecated
|
|
21
|
-
TINY_SAMPLE: 'tiny-sample',
|
|
22
|
-
SAMPLE: 'sample',
|
|
23
|
-
HANDLER: 'handler', // influenced by esm, typer and typescript
|
|
24
20
|
MTA: 'mta',
|
|
25
21
|
CF_MANIFEST: 'cf-manifest',
|
|
26
22
|
HELM: 'helm',
|
|
27
23
|
HELM_UNIFIED_RUNTIME: 'helm-unified-runtime',
|
|
28
24
|
CONTAINERIZE: 'containerize',
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
25
|
+
SAMPLES: 'samples', // deprecated
|
|
26
|
+
TINY_SAMPLE: 'tiny-sample',
|
|
27
|
+
SAMPLE: 'sample',
|
|
28
|
+
HANDLER: 'handler', // influenced by esm, typer and typescript
|
|
29
|
+
TEST: 'test', // needs sample code
|
|
34
30
|
XSUAA: 'xsuaa',
|
|
35
31
|
IAS: 'ias',
|
|
36
32
|
AMS: 'ams',
|
|
37
33
|
HANA: 'hana',
|
|
38
34
|
POSTGRES: 'postgres',
|
|
39
35
|
SQLITE: 'sqlite',
|
|
40
|
-
H2: 'h2',
|
|
41
36
|
LIQUIBASE: 'liquibase',
|
|
42
37
|
REDIS: 'redis',
|
|
38
|
+
H2: 'h2',
|
|
39
|
+
MULTITENANCY: 'multitenancy',
|
|
40
|
+
TOGGLES: 'toggles',
|
|
41
|
+
EXTENSIBILITY: 'extensibility',
|
|
42
|
+
SIDE_BY_SIDE_EXTENSIBILITY: 'side-by-side-extensibility',
|
|
43
|
+
MTX: 'mtx',
|
|
43
44
|
ATTACHMENTS: 'attachments',
|
|
44
45
|
MALWARE_SCANNER: 'malware-scanner',
|
|
45
46
|
LOCAL_MESSAGING: 'local-messaging',
|
package/lib/init/index.js
CHANGED
|
@@ -60,7 +60,13 @@ module.exports = class CDSGenerator {
|
|
|
60
60
|
* @param {any} options, additional options
|
|
61
61
|
*/
|
|
62
62
|
async add(facets) {
|
|
63
|
-
if (!facets?.length)
|
|
63
|
+
if (!facets?.length) {
|
|
64
|
+
const cli = require('../../bin/cds');
|
|
65
|
+
const help = await cli?.load('add', () => ({ help: '' }))?.help ?? '';
|
|
66
|
+
console.log (require('../../bin/help').formatHelp(help))
|
|
67
|
+
process.exitCode=0
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
64
70
|
|
|
65
71
|
this._initialize(null);
|
|
66
72
|
this._greetings();
|
|
@@ -151,11 +157,33 @@ module.exports = class CDSGenerator {
|
|
|
151
157
|
for (const [i, facet] of Object.entries(sorted)) {
|
|
152
158
|
if (!cds.cli.options.dry) console.log(`adding ${term.bold(facet)}`)
|
|
153
159
|
const template = this.templateList[i]
|
|
154
|
-
await template.run()
|
|
155
|
-
await template.combine()
|
|
156
|
-
await template.combineSupported();
|
|
160
|
+
await template.run()
|
|
161
|
+
await template.combine()
|
|
157
162
|
}
|
|
158
163
|
|
|
164
|
+
DEBUG && console.log()
|
|
165
|
+
DEBUG && console.log('plugins active for production:')
|
|
166
|
+
const fromDk = readdirSync(join(__dirname, './template'))
|
|
167
|
+
const { registered } = require('./add')
|
|
168
|
+
const { env4 } = require('./projectReader')
|
|
169
|
+
const processPlugins = async (plugins) => {
|
|
170
|
+
const cmds = Object.values(OPTIONS)
|
|
171
|
+
const byPriority = (a, b) => cmds.indexOf(a) - cmds.indexOf(b)
|
|
172
|
+
const sorted = Array.from(plugins).sort(byPriority)
|
|
173
|
+
for (const plugin of sorted) {
|
|
174
|
+
const Plugin = registered.get(plugin) ?? require('./template/' + plugin)
|
|
175
|
+
const template = new Plugin()
|
|
176
|
+
const inProduction = Plugin.hasInProduction(env4('production')) || cds.cli.argv.includes(plugin) || cds.cli.options.add?.has(plugin)
|
|
177
|
+
DEBUG && console.log(inProduction ? '✅' : '❌', plugin)
|
|
178
|
+
if (inProduction) await template.combine()
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (DEBUG) console.log(`\n ${fromDk.length} from @sap/cds-dk:`)
|
|
183
|
+
await processPlugins(fromDk)
|
|
184
|
+
if (DEBUG) console.log(`\n ${registered.size} from plugins:`)
|
|
185
|
+
await processPlugins(registered.keys())
|
|
186
|
+
|
|
159
187
|
if (cds.env['project-nature'] === 'java') {
|
|
160
188
|
console.log('updating frozen dependencies in package-lock.json…')
|
|
161
189
|
await cmd.spawnCommand('npm' , ['i', '--package-lock-only'], { cwd:cds.root })
|
package/lib/init/merge.js
CHANGED
|
@@ -255,9 +255,12 @@ async function _mergeYAML(into, from, project, semantics = {}) {
|
|
|
255
255
|
let node
|
|
256
256
|
if (inEntry && entryMap.get(inEntry)) {
|
|
257
257
|
node = entryMap.get(inEntry).node // starting from item found in nested array cache
|
|
258
|
-
} else {
|
|
258
|
+
} else if (typeof inEntry === 'string') {
|
|
259
259
|
node = collectionStack[collectionStack.length - 1] // starting from root
|
|
260
|
+
} else {
|
|
261
|
+
return
|
|
260
262
|
}
|
|
263
|
+
|
|
261
264
|
const keys = keyPath.split('.')
|
|
262
265
|
for (const key of keys.slice(0, -1)) {
|
|
263
266
|
if (!node?.get(key) && typeof inEntry === 'string') return // node doesn't exist, will be added by template
|
package/lib/init/plugin.js
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
const { join } = require('path')
|
|
2
|
-
const cds = require('../cds')
|
|
3
|
-
const { readdir } = cds.utils
|
|
4
|
-
|
|
5
1
|
module.exports = class Plugin {
|
|
6
2
|
|
|
7
3
|
/**
|
|
@@ -61,33 +57,4 @@ module.exports = class Plugin {
|
|
|
61
57
|
* Runs the finalize operations.
|
|
62
58
|
*/
|
|
63
59
|
async finalize() { }
|
|
64
|
-
|
|
65
|
-
/* ––––––––––––
|
|
66
|
-
Private APIs
|
|
67
|
-
–––––––––––– */
|
|
68
|
-
|
|
69
|
-
async combineSupported() {
|
|
70
|
-
const DEBUG = cds.log('cli|add')._debug
|
|
71
|
-
DEBUG && console.log()
|
|
72
|
-
DEBUG && console.log('plugins active for production:')
|
|
73
|
-
const fromDk = await readdir(join(__dirname, './template'))
|
|
74
|
-
const { registered } = require('./add')
|
|
75
|
-
const { env4 } = require('./projectReader')
|
|
76
|
-
const processPlugins = async (plugins) => {
|
|
77
|
-
for (const plugin of plugins) {
|
|
78
|
-
const Plugin = registered.get(plugin) ?? require('./template/' + plugin)
|
|
79
|
-
const template = new Plugin()
|
|
80
|
-
const inProduction = Plugin.hasInProduction(env4('production'))
|
|
81
|
-
DEBUG && console.log(inProduction ? '✅' : '❌', plugin)
|
|
82
|
-
if (inProduction) await template.combine()
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (DEBUG) console.log(`\n ${fromDk.length} from @sap/cds-dk:`)
|
|
87
|
-
await processPlugins(fromDk)
|
|
88
|
-
if (DEBUG) console.log(`\n ${registered.size} from plugins:`)
|
|
89
|
-
await processPlugins(registered.keys())
|
|
90
|
-
|
|
91
|
-
DEBUG && console.log()
|
|
92
|
-
}
|
|
93
60
|
}
|
|
@@ -121,7 +121,7 @@ module.exports = new class ProjectReader {
|
|
|
121
121
|
const _isESM = () => pkgJson().type === 'module'
|
|
122
122
|
const _isTypescript = () => !!pkgJson().dependencies?.typescript || !!pkgJson().devDependencies?.typescript
|
|
123
123
|
const _hasTyper = () => !!pkgJson().dependencies?.['@cap-js/cds-typer'] || !!pkgJson().devDependencies?.['@cap-js/cds-typer']
|
|
124
|
-
const _inProd = plugin => require(`./template/${plugin}`).hasInProduction(env)
|
|
124
|
+
const _inProd = plugin => require(`./template/${plugin}`).hasInProduction(env) || cds.cli.argv.includes(plugin) || cds.cli.options.add?.has(plugin)
|
|
125
125
|
const _ui5 = () => pkgJson().sapux
|
|
126
126
|
const _uiEmbedded = () => exists(join(env.folders.app, 'xs-app.json'))
|
|
127
127
|
const _uiModule = () => !_uiEmbedded() && isdir(env.folders.app) && fs.readdirSync(resolve(cds.root, env.folders.app)).length > 0
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
+
{{#withTelemetry}}
|
|
2
3
|
"dependencies": {
|
|
3
4
|
"@cap-js/telemetry": ">=0",
|
|
4
5
|
"@grpc/grpc-js": "^1",
|
|
@@ -6,13 +7,19 @@
|
|
|
6
7
|
"@opentelemetry/exporter-metrics-otlp-grpc": "<0.200",
|
|
7
8
|
"@opentelemetry/host-metrics": "<0.200"
|
|
8
9
|
},
|
|
10
|
+
{{/withTelemetry}}
|
|
9
11
|
"cds": {
|
|
10
12
|
"requires": {
|
|
13
|
+
{{^withTelemetry}}
|
|
14
|
+
"cloud-logging": true
|
|
15
|
+
{{/withTelemetry}}
|
|
16
|
+
{{#withTelemetry}}
|
|
11
17
|
"[{{profile}}]": {
|
|
12
18
|
"telemetry": {
|
|
13
19
|
"kind": "to-cloud-logging"
|
|
14
20
|
}
|
|
15
21
|
}
|
|
22
|
+
{{/withTelemetry}}
|
|
16
23
|
}
|
|
17
24
|
}
|
|
18
25
|
}
|
|
@@ -7,7 +7,7 @@ const { srv4, mtxSidecar4, approuter } = require('../../registries/mta')
|
|
|
7
7
|
module.exports = class extends require('../../plugin') {
|
|
8
8
|
|
|
9
9
|
static hasInProduction(env) {
|
|
10
|
-
return env.requires?.telemetry?.kind === 'to-cloud-logging'
|
|
10
|
+
return env.requires?.telemetry?.kind === 'to-cloud-logging' || env.requires['cloud-logging']
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
options() {
|
|
@@ -24,15 +24,14 @@ module.exports = class extends require('../../plugin') {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
async run() {
|
|
27
|
-
const project = readProject(), {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
27
|
+
const project = readProject(), { isNodejs, isJava } = project
|
|
28
|
+
project.withTelemetry = cds.cli.options['with-telemetry'] || project.hasTelemetry
|
|
29
|
+
if (isNodejs) {
|
|
30
|
+
project.profile ??= 'production'
|
|
31
|
+
await merge(__dirname, 'files/package.json.hbs').into('package.json', { with: project })
|
|
32
|
+
await sort('package.json', 'dependencies')
|
|
33
|
+
} else if (isJava) {
|
|
34
|
+
await merge(__dirname, 'files/java-cdsrc.json.hbs').into('.cdsrc.json', { with: project })
|
|
36
35
|
}
|
|
37
36
|
}
|
|
38
37
|
|
|
@@ -184,7 +184,7 @@ function dataForField(element, artifact, csn, record, data, parent, depth, refer
|
|
|
184
184
|
if (element.key) {
|
|
185
185
|
str = `${artifact.name.split('.').pop()}-${record['$id']}`
|
|
186
186
|
if (element.name === 'locale' && artifact.name.endsWith('texts')) {
|
|
187
|
-
const record = randomFromReferenceData(artifact, csn, referenceData)
|
|
187
|
+
const record = asJson.randomFromReferenceData(artifact, csn, referenceData)
|
|
188
188
|
if (record) return record.locale
|
|
189
189
|
return randomLanguage()
|
|
190
190
|
}
|
|
@@ -273,7 +273,7 @@ function dataForField(element, artifact, csn, record, data, parent, depth, refer
|
|
|
273
273
|
if (!target || depth > MAX_ASSOC_DEPTH)
|
|
274
274
|
return
|
|
275
275
|
|
|
276
|
-
let targetRecord = randomFromReferenceData(target, csn, referenceData)
|
|
276
|
+
let targetRecord = asJson.randomFromReferenceData(target, csn, referenceData)
|
|
277
277
|
if (targetRecord) {
|
|
278
278
|
delete data[target.name] // indicate that existing data is used and no new data shall be created
|
|
279
279
|
delete data[target.name + '.texts'] // also delete associated texts entity
|
|
@@ -318,7 +318,7 @@ function dataForField(element, artifact, csn, record, data, parent, depth, refer
|
|
|
318
318
|
}
|
|
319
319
|
}
|
|
320
320
|
|
|
321
|
-
|
|
321
|
+
asJson.randomFromReferenceData = function(entity, csn, referenceData) {
|
|
322
322
|
const files = Object.entries(referenceData)
|
|
323
323
|
.filter(([, name]) => matchesEntityOrProjection(name, entity, csn))
|
|
324
324
|
.map(([file]) => file)
|
|
@@ -13,8 +13,9 @@ module.exports = class HanaTemplate extends require('../../plugin') {
|
|
|
13
13
|
return 'database support for SAP HANA'
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
static hasInProduction() {
|
|
17
|
-
|
|
16
|
+
static hasInProduction(env) {
|
|
17
|
+
const { dependencies, isJava } = readProject()
|
|
18
|
+
return dependencies?.['@cap-js/hana'] || isJava && env.requires?.db?.kind === 'hana'
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
async run() {
|
|
@@ -94,7 +94,7 @@ module.exports = class Html5RepoTemplate extends require('../../plugin') {
|
|
|
94
94
|
if (hasMultitenancy) {
|
|
95
95
|
relationships.push({
|
|
96
96
|
insert: [html5Runtime, 'name'],
|
|
97
|
-
into: [
|
|
97
|
+
into: [isJava ? srv : mtxSidecar4('gen/mtx/sidecar'), 'requires', 'name']
|
|
98
98
|
})
|
|
99
99
|
}
|
|
100
100
|
await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', {
|