@sap/cds-dk 8.2.3 → 8.4.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.
Files changed (84) hide show
  1. package/CHANGELOG.md +66 -11
  2. package/bin/build.js +1 -1
  3. package/bin/cds.js +17 -4
  4. package/bin/compile/index.js +12 -3
  5. package/bin/deploy/index.js +22 -3
  6. package/bin/env.js +3 -2
  7. package/bin/import.js +24 -14
  8. package/bin/init.js +8 -4
  9. package/bin/repl.js +21 -8
  10. package/bin/util/fuzzySearch.js +8 -5
  11. package/lib/build/plugins/helm/files/subcharts/content-deployment/Chart.yaml +1 -1
  12. package/lib/build/plugins/helm/files/subcharts/content-deployment/values.schema.json +1 -1
  13. package/lib/build/plugins/helm/files/subcharts/content-deployment/values.yaml +1 -1
  14. package/lib/build/plugins/helm/files/subcharts/web-application/Chart.yaml +1 -1
  15. package/lib/build/plugins/helm/files/subcharts/web-application/templates/virtual-service.yaml +23 -12
  16. package/lib/build/plugins/helm/files/subcharts/web-application/values.schema.json +1 -1
  17. package/lib/build/plugins/helm/files/subcharts/web-application/values.yaml +2 -2
  18. package/lib/build/util.js +32 -20
  19. package/lib/compile/to-mermaid.js +87 -0
  20. package/lib/deploy/to-hana/hana.js +2 -21
  21. package/lib/env/schemas/cds-rc.js +174 -2
  22. package/lib/import/asyncapi/parserContext.js +4 -30
  23. package/lib/import/common.js +2 -2
  24. package/lib/import/importapi.js +3 -3
  25. package/lib/import/odata/v2parser.js +3 -2
  26. package/lib/import/openapi/importOpenAPI.js +622 -537
  27. package/lib/import/openapi/utilities.js +7 -2
  28. package/lib/init/constants.js +2 -1
  29. package/lib/init/index.js +4 -0
  30. package/lib/init/merge.js +2 -2
  31. package/lib/init/mvn.js +2 -2
  32. package/lib/init/projectReader.js +2 -1
  33. package/lib/init/registries/mta.js +8 -1
  34. package/lib/init/registries/xs-app.js +10 -0
  35. package/lib/init/template/approuter/files/package.json +1 -1
  36. package/lib/init/template/cf-manifest/files/manifest.yml.hbs +3 -1
  37. package/lib/init/template/cf-manifest/index.js +2 -0
  38. package/lib/init/template/cloud-logging/files/mta.yaml.hbs +13 -2
  39. package/lib/init/template/cloud-logging/files/{package.json → package.json.hbs} +5 -1
  40. package/lib/init/template/cloud-logging/index.js +4 -3
  41. package/lib/init/template/data/as-csv.js +6 -0
  42. package/lib/init/template/data/as-json.js +8 -1
  43. package/lib/init/template/data/index.js +1 -1
  44. package/lib/init/template/destination/files/mta.yaml.hbs +5 -5
  45. package/lib/init/template/dynatrace/files/mta.yaml.hbs +22 -6
  46. package/lib/init/template/dynatrace/files/package.json.hbs +5 -2
  47. package/lib/init/template/dynatrace/files/values.yaml +15 -0
  48. package/lib/init/template/dynatrace/index.js +10 -5
  49. package/lib/init/template/enterprise-messaging-shared/index.js +1 -1
  50. package/lib/init/template/file-based-messaging/index.js +1 -1
  51. package/lib/init/template/hana/files/package.json.hbs +2 -0
  52. package/lib/init/template/hana/index.js +1 -1
  53. package/lib/init/template/handler/index.js +16 -1
  54. package/lib/init/template/helm/files/values.yaml.hbs +2 -2
  55. package/lib/init/template/helm/index.js +6 -1
  56. package/lib/init/template/html5-repo/files/app-package.json.hbs +3 -1
  57. package/lib/init/template/html5-repo/files/ui5-deploy.yaml.hbs +7 -0
  58. package/lib/init/template/html5-repo/index.js +3 -1
  59. package/lib/init/template/local-messaging/index.js +1 -1
  60. package/lib/init/template/mta/files/mta.yaml.hbs +1 -1
  61. package/lib/init/template/mta/index.js +2 -0
  62. package/lib/init/template/nodejs/files/.vscode/extensions.json +0 -5
  63. package/lib/init/template/nodejs/files/.vscode/settings.json +1 -1
  64. package/lib/init/template/nodejs/files/.vscode/tasks.json +0 -2
  65. package/lib/init/template/nodejs/files/package.json.hbs +1 -1
  66. package/lib/init/template/postgres/index.js +1 -1
  67. package/lib/init/template/redis-messaging/index.js +1 -1
  68. package/lib/init/template/side-by-side-extensibility/files/mta.yaml.hbs +40 -0
  69. package/lib/init/template/side-by-side-extensibility/files/package.json.hbs +17 -0
  70. package/lib/init/template/side-by-side-extensibility/index.js +34 -0
  71. package/lib/init/template/typer/index.js +2 -1
  72. package/lib/init/template/typescript/files/package.json +2 -2
  73. package/lib/init/template/workzone-standard/files/manifest.json.hbs +15 -1
  74. package/lib/init/template/workzone-standard/files/mta.yaml.hbs +11 -2
  75. package/lib/init/template/workzone-standard/files/xs-app.json.hbs +18 -0
  76. package/lib/init/template/workzone-standard/index.js +25 -7
  77. package/lib/init/template/xsuaa/index.js +1 -1
  78. package/lib/mtx/auth_manager.js +7 -5
  79. package/lib/mtx/util/errors.js +4 -4
  80. package/lib/util/fs.js +1 -1
  81. package/lib/util/jsonc.js +1 -1
  82. package/lib/util/jsonc.pegjs +6 -2
  83. package/npm-shrinkwrap.json +78 -149
  84. package/package.json +1 -1
@@ -2,8 +2,13 @@ module.exports = { cdsName, nameFromPath, pathAndMethod, serviceName };
2
2
 
3
3
  function cdsName(oasName) {
4
4
  if (oasName === "") return "_";
5
+ if (typeof oasName === "number") return `_${JSON.stringify(oasName)}`;
5
6
  let name = oasName;
6
- if (name.match(/^(\p{Nd}|\p{Mn}|\p{Mc}|\p{Pc}|\p{Cf})/u)) name = "_" + name;
7
+ if (
8
+ !name.startsWith("_") &&
9
+ name.match(/^(\p{Nd}|\p{Mn}|\p{Mc}|\p{Pc}|\p{Cf})/u)
10
+ )
11
+ name = "_" + name;
7
12
  return name.replace(/[^_\p{L}\p{Nl}\p{Nd}\p{Mn}\p{Mc}\p{Pc}\p{Cf}]/gu, "_");
8
13
  //TODO: shorten if longer than 128 characters
9
14
  }
@@ -15,7 +20,7 @@ function nameFromPath(path, method) {
15
20
  .replace(/{[^}]+}/g, ".")
16
21
  .replace(/\/\./g, "_")
17
22
  .replace(/[^_\p{L}\p{Nl}\p{Nd}\p{Mn}\p{Mc}\p{Pc}\p{Cf}]/gu, "_");
18
- if (cleanPath === "") cleanPath = "_";
23
+ if (cleanPath === "") cleanPath = "_root";
19
24
  //TODO: shorten if longer than 128 characters
20
25
  return method === "get" ? cleanPath : `${cleanPath}_${method}`;
21
26
  }
@@ -5,7 +5,7 @@ module.exports = {
5
5
  COMMAND_ADD: 'add',
6
6
 
7
7
  JAVA_LTS_VERSIONS: [17, 21],
8
- MAVEN_ARCHETYPE_VERSION: '3.2.0',
8
+ MAVEN_ARCHETYPE_VERSION: '3.3.1',
9
9
 
10
10
  OPTIONS: Object.freeze({
11
11
  COMPLETION: 'completion',
@@ -24,6 +24,7 @@ module.exports = {
24
24
  MULTITENANCY: 'multitenancy',
25
25
  TOGGLES: 'toggles',
26
26
  EXTENSIBILITY: 'extensibility',
27
+ SIDE_BY_SIDE_EXTENSIBILITY: 'side-by-side-extensibility',
27
28
  MTX: 'mtx',
28
29
  XSUAA: 'xsuaa',
29
30
  HANA: 'hana',
package/lib/init/index.js CHANGED
@@ -265,6 +265,10 @@ module.exports = class CDSGenerator {
265
265
  // set is ordered ... always
266
266
  options.add = new Set(trimmedTokens);
267
267
 
268
+ if (options?.java) { // --java -> --add java
269
+ options.add.add('java')
270
+ }
271
+
268
272
  if (cds.cli.command === COMMAND_INIT && !options.add.has(JAVA)) {
269
273
  options.add.add(NODEJS);
270
274
  }
package/lib/init/merge.js CHANGED
@@ -162,8 +162,8 @@ async function _mergeYAML(into, from, project, semantics = {}) {
162
162
 
163
163
  let collectionStack = [target.contents]
164
164
 
165
- const _getProperty = (object, keyPath) => keyPath.split('.').reduce((p, k) => p && p[k], object)
166
- const _getYAMLProperty = (object, keyPath) => keyPath.split('.').reduce((p, k) => p && p.get(k), object)
165
+ const _getProperty = (object, keyPath) => keyPath.split('.').filter(k => k).reduce((p, k) => p && p[k], object)
166
+ const _getYAMLProperty = (object, keyPath) => keyPath.split('.').filter(k => k).reduce((p, k) => p && p.get(k), object)
167
167
 
168
168
  const _validateWhere = (node, dict, index) => {
169
169
  const _addToMap = entries => entries?.filter(entry => {
package/lib/init/mvn.js CHANGED
@@ -17,8 +17,8 @@ module.exports.add = async function (feature) {
17
17
  if (javaMvn) _scan(javaMvn).forEach(([k,v]) => params.set(k,v))
18
18
  const archetypeVersion = params.get('-DarchetypeVersion') ?? MAVEN_ARCHETYPE_VERSION
19
19
  if (feature === HANA) { // REVISIT: compat for HANA until -Dfeature HANA is provided by Java
20
- params.set(`com.sap.cds:cds-maven-plugin:${archetypeVersion}:addTargetPlatform`)
21
- params.set(`-DtargetPlatform`, `cloudfoundry`) // REVISIT: Should get rid of CF dependency for Kyma scenarios
20
+ params.set(`com.sap.cds:cds-maven-plugin:${archetypeVersion}:add`)
21
+ params.set(`-Dfeature`, `CF`) // REVISIT: Should get rid of CF dependency for Kyma scenarios
22
22
  } else {
23
23
  params.set(`com.sap.cds:cds-maven-plugin:${archetypeVersion}:add`)
24
24
  params.set(`-Dfeature`, feature)
@@ -89,10 +89,12 @@ module.exports = new class ProjectReader {
89
89
  * @property {boolean} hasApprouter Indicates if the project uses the SAP Application Router.
90
90
  * @property {boolean} hasHtml5Repo Indicates if the project uses the SAP BTP HTML5 Application Repository.
91
91
  * @property {boolean} hasPortal Indicates if the project uses the SAP Cloud Portal service.
92
+ * @property {boolean} hasWorkzoneStandard Indicates if the project uses the SAP Build Work Zone, Standard Edition service.
92
93
  * @property {boolean} hasDestination Indicates if the project uses the SAP BTP Destination service.
93
94
  * @property {boolean} hasMTXRoute Indicates if the approuter should have a multitenant route.
94
95
  * @property {boolean} hasMTXRouteJava Indicates if the approuter should have a multitenant subscription route (java).
95
96
  * @property {boolean} hasMalwareScanner Indicates if the project uses the SAP Malware Scanning service.
97
+ * @property {boolean} hasDynatrace Indicates if the project uses Dynatrace.
96
98
  *
97
99
  */
98
100
 
@@ -116,7 +118,6 @@ module.exports = new class ProjectReader {
116
118
  const isApp = name => name !== 'appconfig' && !name.startsWith('_') && name !== 'router' && name !== 'portal'
117
119
  const reserved = {
118
120
  has: x => _inProd(x),
119
- shortcut: () => true,
120
121
  profile: () => cds.cli.options?.for,
121
122
  language: () => exists('pom.xml') ? 'java' : 'nodejs',
122
123
  isJava: () => _isJava(),
@@ -5,7 +5,8 @@ const srvNode4 = path => ({ in: 'modules', where: { type: 'nodejs', path } })
5
5
  const srvJava4 = path => ({ in: 'modules', where: { type: 'java', path } })
6
6
 
7
7
  // REVISIT: Clean up
8
- const isJava = process.argv[process.argv.indexOf('--add') + 1].split(',').includes('java') || cds.env['project-nature'] === 'java' || cds.cli.options?.add?.has('java')
8
+ const isJava = process.argv[process.argv.indexOf('--add') + 1].split(/[,\s+]/).includes('java') || cds.env['project-nature'] === 'java' || cds.cli.options?.add?.has('java') || process.argv.includes('--java')
9
+
9
10
  const srv4 = isJava ? srvJava4 : srvNode4
10
11
 
11
12
  const approuter = { in: 'modules', where: { type: 'approuter.nodejs' } }
@@ -25,6 +26,11 @@ const destinations = {
25
26
  where: { type: 'com.sap.application.content', 'build-parameters.no-source': true }
26
27
  }
27
28
 
29
+ const destinationSideBySideExtensibility = {
30
+ in: [destinations, 'parameters.content.subaccount.destinations' ],
31
+ where: { URL: '~{srv-api/srv-url}', Authentication: 'OAuth2ClientCredentials' }
32
+ }
33
+
28
34
  const connectivity = {
29
35
  in: 'resources',
30
36
  where: { type: 'org.cloudfoundry.managed-service', 'parameters.service': 'connectivity' }
@@ -186,6 +192,7 @@ module.exports = {
186
192
  xsuaa,
187
193
  destination,
188
194
  destinations,
195
+ destinationSideBySideExtensibility,
189
196
  connectivity,
190
197
  enterpriseMessaging,
191
198
  kafkaMessaging,
@@ -0,0 +1,10 @@
1
+
2
+
3
+ const odataApi = {
4
+ in: 'routes',
5
+ where: { target: '/odata/$1' }
6
+ }
7
+
8
+ module.exports = {
9
+ odataApi
10
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "approuter",
3
3
  "dependencies": {
4
- "@sap/approuter": "^16.0.0"
4
+ "@sap/approuter": "^17.0.0"
5
5
  },
6
6
  "engines": {
7
7
  "node": "^20.0.0"
@@ -20,7 +20,9 @@ applications:
20
20
  disk_quota: 512M
21
21
  env:
22
22
  SPRING_PROFILES_ACTIVE: cloud
23
- buildpack: java_buildpack
23
+ JBP_CONFIG_COMPONENTS: "jres: ['com.sap.xs.java.buildpack.jdk.SAPMachineJDK']"
24
+ JBP_CONFIG_SAP_MACHINE_JDK: '{ version: 21.+ }'
25
+ buildpack: sap_java_buildpack_jakarta
24
26
  {{/isJava}}
25
27
  services:
26
28
  {{#hasHana}}
@@ -3,6 +3,7 @@ const cds = require('../../../cds')
3
3
  const { exists } = require('../../../cds').utils
4
4
  const { readProject } = require('../../projectReader')
5
5
  const { renderAndCopy } = require('../../template')
6
+ const mvn = require('../../mvn')
6
7
  const MANIFEST_FILE = 'manifest.yml'
7
8
  const SERVICES_MANIFEST_FILE = 'services-manifest.yml'
8
9
 
@@ -29,5 +30,6 @@ module.exports = class CfManifestTemplate extends require('../../plugin') {
29
30
  async run() {
30
31
  const project = readProject()
31
32
  await renderAndCopy(join(__dirname, 'files'), cds.root, project)
33
+ if (project.isJava) await mvn.add('CF')
32
34
  }
33
35
  }
@@ -3,6 +3,17 @@ modules:
3
3
  - name: {{appName}}-srv
4
4
  type: {{language}}
5
5
  path: {{& srvPath}}
6
+ {{#isJava}}
7
+ properties:
8
+ JBP_CONFIG_JAVA_OPTS:
9
+ from_environment: false
10
+ java_opts: >
11
+ -javaagent:META-INF/.sap_java_buildpack/otel_agent/opentelemetry-javaagent.jar
12
+ -Dotel.javaagent.extensions=META-INF/.sap_java_buildpack/otel_agent_extension/otel-agent-ext-java.jar
13
+ OTEL_METRICS_EXPORTER: cloud-logging
14
+ OTEL_TRACES_EXPORTER: cloud-logging
15
+ OTEL_LOGS_EXPORTER: none
16
+ {{/isJava}}
6
17
  requires:
7
18
  - name: {{appName}}-cloud-logging
8
19
  - name: {{appName}}-mtx
@@ -21,5 +32,5 @@ resources:
21
32
  service: cloud-logging
22
33
  service-plan: {{cloudLoggingServicePlan}}
23
34
  config:
24
- ingest_otlp:
25
- enabled: true
35
+ ingest_otlp:
36
+ enabled: true
@@ -8,7 +8,11 @@
8
8
  },
9
9
  "cds": {
10
10
  "requires": {
11
- "telemetry": "to-cloud-logging"
11
+ "[{{profile}}]": {
12
+ "telemetry": {
13
+ "kind": "to-cloud-logging"
14
+ }
15
+ }
12
16
  }
13
17
  }
14
18
  }
@@ -30,9 +30,10 @@ module.exports = class extends require('../../plugin') {
30
30
  }
31
31
 
32
32
  async run() {
33
- const { hasTelemetry } = readProject()
34
- if (cds.cli.options['with-telemetry'] || hasTelemetry) {
35
- await merge(__dirname, 'files/package.json').into('package.json')
33
+ const project = readProject(), { hasTelemetry, isNodejs } = project
34
+ if (isNodejs && (cds.cli.options['with-telemetry'] || hasTelemetry)) {
35
+ project.profile ??= 'production'
36
+ await merge(__dirname, 'files/package.json.hbs').into('package.json', { with: project })
36
37
  await sort('package.json', 'dependencies')
37
38
  }
38
39
  }
@@ -39,6 +39,12 @@ module.exports = async (data={}, csn, { headerOnly=false, separator=',' }={}) =>
39
39
  }
40
40
  record.push(...Object.values(value))
41
41
  }
42
+ else if (element.is_struct) {
43
+ if (i === 0) {
44
+ header.push(...Object.keys(value).map(structField => name + '_' + structField))
45
+ }
46
+ record.push(...Object.values(value))
47
+ }
42
48
  else {
43
49
  if (i === 0) header.push(name)
44
50
  if (Array.isArray(value)) { // `array of` / `many`
@@ -121,9 +121,16 @@ function dataForField(element, entity, csn, record, data, parentEntity, depth, r
121
121
  else if (element.items?.type) // `array of` / `many` with simple type
122
122
  return [ dataForField(element.items, entity, csn, record, data, null, depth+1, referenceData) ]
123
123
 
124
+ if (element.is_struct) {
125
+ let struct = {}
126
+ for (const el of element.elements) {
127
+ struct[el.name] = dataForField(el, entity, csn, record, data, null, depth+1, referenceData)
128
+ }
129
+ return struct
130
+ }
131
+
124
132
  const type = element._type || element.type
125
133
  switch (type) {
126
- case undefined: return
127
134
  case 'cds.Time':
128
135
  return '22:59:53'
129
136
 
@@ -67,7 +67,7 @@ module.exports = class DataTemplate extends require('../../plugin') {
67
67
  : getDefaultTargetFolder(env)
68
68
  dest = resolve(cds.root, dest)
69
69
 
70
- let csn = await cds.load(cds.env.roots) // normal CSN
70
+ let csn = await cds.load([cds.env.roots, join(`${cds.env.folders.srv}`, `external`) ]) // normal CSN. Default paths and models imported with `cds import`
71
71
  // Skip of unused reuse entities like Language, Country, Currency
72
72
  csn = cds.minify(csn)
73
73
  csn = cds.reflect(csn) // reflected model (adds additional helper functions)
@@ -31,14 +31,14 @@ resources:
31
31
  destinations:
32
32
  - Name: {{appName}}-srv-api
33
33
  URL: ~{srv-api/srv-url}
34
- Authentication: OAuth2UserTokenExchange
34
+ Authentication: NoAuthentication
35
35
  Type: HTTP
36
36
  ProxyType: Internet
37
37
  HTML5.ForwardAuthToken: true
38
38
  HTML5.DynamicDestination: true
39
- - Authentication: NoAuthentication
40
- Name: ui5
41
- ProxyType: Internet
42
- Type: HTTP
39
+ - Name: ui5
43
40
  URL: https://ui5.sap.com
41
+ Authentication: NoAuthentication
42
+ Type: HTTP
43
+ ProxyType: Internet
44
44
  {{/hasHtml5Repo}}
@@ -3,8 +3,28 @@ modules:
3
3
  - name: {{appName}}-srv
4
4
  type: {{language}}
5
5
  path: {{& srvPath}}
6
+ {{#isJava}}
7
+ properties:
8
+ JBP_CONFIG_JAVA_OPTS:
9
+ from_environment: false
10
+ java_opts: >
11
+ -javaagent:META-INF/.sap_java_buildpack/otel_agent/opentelemetry-javaagent.jar
12
+ -Dotel.javaagent.extensions=META-INF/.sap_java_buildpack/otel_agent_extension/otel-agent-ext-java.jar
13
+ -Dotel.javaagent.extension.sap.cf.binding.dynatrace.metrics.token-name=ingest_apitoken
14
+ OTEL_METRICS_EXPORTER: dynatrace
15
+ OTEL_TRACES_EXPORTER: none
16
+ OTEL_LOGS_EXPORTER: none
17
+ {{/isJava}}
6
18
  requires:
7
19
  - name: {{appName}}-dynatrace
20
+ parameters:
21
+ config:
22
+ tokens:
23
+ - name: ingest_apitoken
24
+ scopes:
25
+ - openTelemetryTrace.ingest
26
+ - metrics.ingest
27
+
8
28
  - name: {{appName}}-mtx
9
29
  type: nodejs
10
30
  path: {{#isNodejs}}gen/{{/isNodejs}}mtx/sidecar
@@ -15,10 +35,6 @@ resources:
15
35
  type: org.cloudfoundry.managed-service
16
36
  parameters:
17
37
  service: dynatrace
18
- service-plan: standard
38
+ service-plan: environment
19
39
  config:
20
- tokens:
21
- - name: ingest_apitoken
22
- scopes:
23
- - openTelemetryTrace.ingest
24
- - metrics.ingest
40
+ environment_name: {{appName}}
@@ -2,13 +2,16 @@
2
2
  "dependencies": {
3
3
  "@cap-js/telemetry": ">=0",
4
4
  "@opentelemetry/exporter-metrics-otlp-proto": "^0"{{#hasHelm}},
5
- "@opentelemetry/exporter-trace-otlp-proto": "^0",
6
5
  "@opentelemetry/host-metrics": "^0"
7
6
  {{/hasHelm}}
8
7
  },
9
8
  "cds": {
10
9
  "requires": {
11
- "telemetry": "to-dynatrace"
10
+ "[{{profile}}]": {
11
+ "telemetry": {
12
+ "kind": "to-dynatrace"
13
+ }
14
+ }
12
15
  }
13
16
  }
14
17
  }
@@ -0,0 +1,15 @@
1
+ srv:
2
+ bindings:
3
+ dynatrace:
4
+ serviceInstanceName: dynatrace
5
+ parameters:
6
+ tokens:
7
+ - name: ingest_apitoken
8
+ scopes:
9
+ - openTelemetryTrace.ingest
10
+ - metrics.ingest
11
+ dynatrace:
12
+ serviceOfferingName: dynatrace
13
+ servicePlanName: environment
14
+ parameters:
15
+ environment_name: DYNATRACE # (Mandatory) maximum of 16 characters and can only comprise of uppercase letters and digits.
@@ -10,20 +10,21 @@ module.exports = class extends require('../../plugin') {
10
10
  }
11
11
 
12
12
  async canRun() {
13
- const { hasMta, hasHelm, hasHelmUnifiedRuntime } = readProject()
14
- if ((hasHelmUnifiedRuntime || hasHelm) && !hasMta) throw `'cds add dynatrace' is not available for Kyma yet`
15
13
  return true
16
14
  }
17
15
 
18
16
  async run() {
19
17
  const project = readProject()
20
- await merge(__dirname, 'files/package.json.hbs').into('package.json', { with: project })
21
- await sort('package.json', 'dependencies')
18
+ if (project.isNodejs) {
19
+ project.profile ??= 'production'
20
+ await merge(__dirname, 'files/package.json.hbs').into('package.json', { with: project })
21
+ await sort('package.json', 'dependencies')
22
+ }
22
23
  }
23
24
 
24
25
  async combine() {
25
26
  const project = readProject()
26
- const { hasMta, isJava, hasMultitenancy, srvPath } = project
27
+ const { hasMta, hasHelm, hasHelmUnifiedRuntime, isJava, hasMultitenancy, srvPath } = project
27
28
 
28
29
  if (hasMta) {
29
30
  const dynatrace = {
@@ -51,5 +52,9 @@ module.exports = class extends require('../../plugin') {
51
52
  with: project, additions, relationships
52
53
  })
53
54
  }
55
+
56
+ if (hasHelm || hasHelmUnifiedRuntime) {
57
+ await merge(__dirname, 'files', 'values.yaml').into('chart/values.yaml')
58
+ }
54
59
  }
55
60
  }
@@ -34,7 +34,7 @@ module.exports = class EnterpriseMessagingSharedTemplate extends require('../../
34
34
  const project = readProject()
35
35
  const { configFile, isNodejs } = project
36
36
  if (isNodejs) {
37
- project.shortcut = !(await read(configFile)).cds?.requires?.messaging?.kind
37
+ project.shortcut = typeof (await read(configFile)).cds?.requires?.messaging !== 'object'
38
38
  project.cloudevents = cds.cli.options.cloudevents
39
39
  await merge(__dirname, 'files/package.json.hbs').into(configFile, { with: project })
40
40
  }
@@ -21,7 +21,7 @@ module.exports = class FileBasedMessagingTemplate extends require('../../plugin'
21
21
  async run() {
22
22
  const project = readProject()
23
23
  const { configFile } = project
24
- project.shortcut = !(await read(configFile)).cds?.requires?.messaging?.kind
24
+ project.shortcut = typeof (await read(configFile)).cds?.requires?.messaging !== 'object'
25
25
  await merge(__dirname, 'files/package.json.hbs').into(configFile, { with: project })
26
26
  }
27
27
  }
@@ -1,7 +1,9 @@
1
1
  {
2
+ {{#isNodejs}}
2
3
  "dependencies": {
3
4
  "@cap-js/hana": "^1"
4
5
  },
6
+ {{/isNodejs}}
5
7
  {{#isNodejs}}
6
8
  "cds": {
7
9
  {{/isNodejs}}
@@ -20,7 +20,7 @@ module.exports = class HanaTemplate extends require('../../plugin') {
20
20
  async run() {
21
21
  const project = readProject()
22
22
  const { isJava, configFile, db } = project
23
- project.shortcut = !(await read(configFile)).cds?.requires?.db?.kind
23
+ project.shortcut = typeof (await read(configFile)).cds?.requires?.db !== 'object'
24
24
 
25
25
  // REVISIT: Let cds build generate those by default
26
26
  await merge(__dirname, 'files/src/.hdiconfig').into(join(db.folder, 'src/.hdiconfig'))
@@ -5,7 +5,22 @@ const mvn = require('../../mvn')
5
5
  module.exports = class Handler extends require('../../plugin') {
6
6
 
7
7
  static help() {
8
- return 'add handler stubs'
8
+ return 'add handler stubs for actions and functions (Java)'
9
+ }
10
+
11
+ options() {
12
+ return {
13
+ 'filter': {
14
+ type: 'string',
15
+ short: 'f',
16
+ help: `Filter actions or functions by name prefix. Regular expressions are not supported.`
17
+ },
18
+ 'out': {
19
+ type: 'string',
20
+ short: 'o',
21
+ help: 'Specify a custom output directory inside the `handlers` directory. The default is `handlers`.'
22
+ }
23
+ }
9
24
  }
10
25
 
11
26
  canRun() {
@@ -26,6 +26,6 @@ srv:
26
26
  memory: {{#isJava}}1G{{/isJava}}{{^isJava}}500M{{/isJava}}
27
27
  health:
28
28
  liveness:
29
- path: {{#isJava}}/actuator/health{{/isJava}}{{^isJava}}/health{{/isJava}}
29
+ path: {{#isJava}}/actuator/health/liveness{{/isJava}}{{^isJava}}/health{{/isJava}}
30
30
  readiness:
31
- path: {{#isJava}}/actuator/health{{/isJava}}{{^isJava}}/health{{/isJava}}
31
+ path: {{#isJava}}/actuator/health/readiness{{/isJava}}{{^isJava}}/health{{/isJava}}
@@ -5,6 +5,7 @@ const { readProject } = require('../../projectReader')
5
5
  const { merge } = require('../../merge')
6
6
  const { ask4 } = require('../../../util/question')
7
7
  const { execSync } = require('child_process')
8
+ const { mvn } = require('../../add')
8
9
 
9
10
  module.exports = class HelmTemplate extends require('../../plugin') {
10
11
 
@@ -90,10 +91,11 @@ module.exports = class HelmTemplate extends require('../../plugin') {
90
91
  await merge(__dirname, 'files/Chart.yaml.hbs').into('chart/Chart.yaml', { with: project })
91
92
  await merge(__dirname, 'files/values.yaml.hbs').into('chart/values.yaml', { with: project })
92
93
  await this._mergeDependency('web-application', 'srv')
94
+ if (project.isJava) await mvn.add('k8s')
93
95
  }
94
96
 
95
97
  async combine() {
96
- const { hasDestination, hasEnterpriseMessaging, hasEnterpriseMessagingShared, hasHana, hasMultitenancy, hasXsuaa, hasHtml5Repo, hasApprouter, hasKafka, hasAttachments, hasPortal, hasMalwareScanner } = readProject()
98
+ const { hasDestination, hasEnterpriseMessaging, hasEnterpriseMessagingShared, hasHana, hasMultitenancy, hasXsuaa, hasHtml5Repo, hasApprouter, hasKafka, hasAttachments, hasPortal, hasMalwareScanner, hasDynatrace } = readProject()
97
99
 
98
100
  if (hasApprouter) {
99
101
  await this._mergeDependency('web-application', 'approuter')
@@ -140,6 +142,9 @@ module.exports = class HelmTemplate extends require('../../plugin') {
140
142
  if (hasMalwareScanner) {
141
143
  await this._mergeDependency('service-instance', 'malware-scanner')
142
144
  }
145
+ if (hasDynatrace) {
146
+ await this._mergeDependency('service-instance', 'dynatrace')
147
+ }
143
148
  }
144
149
 
145
150
  async _mergeDependency(name, alias) {
@@ -8,11 +8,13 @@
8
8
  "start": "ui5 serve"
9
9
  },
10
10
  "devDependencies": {
11
- "@ui5/cli": "^3",
11
+ {{#hasWorkzoneStandard}}"@sap/ui5-builder-webide-extension": "^1.1.9",{{/hasWorkzoneStandard}}
12
+ "@ui5/cli": "^4",
12
13
  "ui5-task-zipper": "^3"
13
14
  },
14
15
  "ui5": {
15
16
  "dependencies": [
17
+ {{#hasWorkzoneStandard}}"@sap/ui5-builder-webide-extension",{{/hasWorkzoneStandard}}
16
18
  "ui5-task-zipper"
17
19
  ]
18
20
  }
@@ -13,6 +13,13 @@ builder:
13
13
  - "/test/**"
14
14
  - "/localService/**"
15
15
  customTasks:
16
+ {{#hasWorkzoneStandard}}
17
+ - name: webide-extension-task-updateManifestJson
18
+ afterTask: replaceVersion
19
+ configuration:
20
+ appFolder: webapp
21
+ destDir: dist
22
+ {{/hasWorkzoneStandard}}
16
23
  - name: ui5-task-zipper
17
24
  afterTask: generateVersionInfo
18
25
  configuration:
@@ -2,6 +2,7 @@ const { join } = require('path')
2
2
  const { readProject } = require('../../projectReader')
3
3
  const { merge } = require('../../merge')
4
4
  const { srv4, html5RepoHost, html5Runtime, appDeployer, approuter, mtxSidecar4 } = require('../../registries/mta')
5
+ const { odataApi } = require('../../registries/xs-app')
5
6
 
6
7
  module.exports = class Html5RepoTemplate extends require('../../plugin') {
7
8
 
@@ -52,7 +53,8 @@ module.exports = class Html5RepoTemplate extends require('../../plugin') {
52
53
 
53
54
  await Promise.all(apps.map(async ({app}) => {
54
55
  project.app = app
55
- await merge(__dirname, 'files/xs-app.json.hbs').into(join(appPath, app, 'xs-app.json'), { project })
56
+ const additions = [odataApi]
57
+ await merge(__dirname, 'files/xs-app.json.hbs').into(join(appPath, app, 'xs-app.json'), { with: project, additions })
56
58
  }))
57
59
 
58
60
  if (hasMultitenancy) {
@@ -22,7 +22,7 @@ module.exports = class LocalMessagingTemplate extends require('../../plugin') {
22
22
  async run() {
23
23
  const project = readProject()
24
24
  const { configFile } = project
25
- project.shortcut = !(await read(configFile)).cds?.requires?.messaging?.kind
25
+ project.shortcut = typeof (await read(configFile)).cds?.requires?.messaging !== 'object'
26
26
  await merge(__dirname, 'files/package.json.hbs').into(configFile, { with: project })
27
27
  }
28
28
  }
@@ -29,7 +29,7 @@ modules:
29
29
  parameters:
30
30
  buildpack: sap_java_buildpack_jakarta
31
31
  readiness-health-check-type: http
32
- readiness-health-check-http-endpoint: /actuator/health
32
+ readiness-health-check-http-endpoint: /actuator/health/readiness
33
33
  properties:
34
34
  SPRING_PROFILES_ACTIVE: cloud,sandbox
35
35
  JBP_CONFIG_COMPONENTS: "jres: ['com.sap.xs.java.buildpack.jre.SAPMachineJRE']"
@@ -5,6 +5,7 @@ const { bold } = require('../../../util/term')
5
5
  const { copyRenderedYAML } = require('../../../util/fs')
6
6
  const { readProject } = require('../../projectReader')
7
7
  const { merge, sort } = require('../../merge')
8
+ const { mvn } = require('../../add')
8
9
 
9
10
  module.exports = class MtaTemplate extends require('../../plugin') {
10
11
 
@@ -23,6 +24,7 @@ module.exports = class MtaTemplate extends require('../../plugin') {
23
24
  }
24
25
  await merge(__dirname, 'files/package.json').into('package.json')
25
26
  await sort('package.json', 'devDependencies')
27
+ if (project.isJava) await mvn.add('cf')
26
28
  }
27
29
 
28
30
  async finalize() {
@@ -1,8 +1,4 @@
1
1
  {
2
- // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
3
- // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
4
-
5
- // List of extensions which should be recommended for users of this workspace.
6
2
  "recommendations": [
7
3
  "SAPSE.vscode-cds",
8
4
  "dbaeumer.vscode-eslint",
@@ -11,7 +7,6 @@
11
7
  "qwtel.sqlite-viewer",
12
8
  "humao.rest-client"
13
9
  ],
14
- // List of extensions recommended by VS Code that should not be recommended for users of this workspace.
15
10
  "unwantedRecommendations": [
16
11
 
17
12
  ]
@@ -8,4 +8,4 @@
8
8
  // "tab",
9
9
  // "tsv"
10
10
  ]
11
- }
11
+ }
@@ -1,6 +1,4 @@
1
1
  {
2
- // See https://go.microsoft.com/fwlink/?LinkId=733558
3
- // for the documentation about the tasks.json format
4
2
  "version": "2.0.0",
5
3
  "tasks": [
6
4
  {