@sap/cds-dk 9.4.1 → 9.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/bin/data-products/index.js +10 -2
  3. package/bin/data-products/prepare-csn.js +63 -26
  4. package/bin/help.js +2 -2
  5. package/bin/import.js +7 -2
  6. package/bin/up.js +25 -4
  7. package/bin/util/containerize.js +142 -0
  8. package/lib/build/buildTaskEngine.js +5 -2
  9. package/lib/build/plugin.js +1 -1
  10. package/lib/build/plugins/helm/index.js +6 -7
  11. package/lib/build/provider/hana/index.js +10 -2
  12. package/lib/import/common.js +3 -3
  13. package/lib/import/message.js +1 -1
  14. package/lib/init/constants.js +3 -1
  15. package/lib/init/index.js +4 -5
  16. package/lib/init/projectReader.js +101 -77
  17. package/lib/init/registries/mta.js +3 -0
  18. package/lib/init/registries/xs-app.js +7 -1
  19. package/lib/init/template/ams/index.js +7 -6
  20. package/lib/init/template/app-frontend/files/mta.yaml.hbs +0 -7
  21. package/lib/init/template/app-frontend/index.js +2 -2
  22. package/lib/init/template/application-logging/index.js +13 -10
  23. package/lib/init/template/approuter/files/mta.yaml.hbs +7 -0
  24. package/lib/init/template/approuter/index.js +30 -18
  25. package/lib/init/template/attachments/index.js +3 -3
  26. package/lib/init/template/audit-logging/index.js +4 -4
  27. package/lib/init/template/cloud-logging/index.js +13 -10
  28. package/lib/init/template/connectivity/index.js +3 -3
  29. package/lib/init/template/containerize/files/containerize.yaml.hbs +1 -2
  30. package/lib/init/template/destination/index.js +5 -9
  31. package/lib/init/template/dynatrace/index.js +13 -10
  32. package/lib/init/template/enterprise-messaging/index.js +5 -5
  33. package/lib/init/template/enterprise-messaging-shared/index.js +4 -4
  34. package/lib/init/template/extensibility/index.js +2 -2
  35. package/lib/init/template/file-based-messaging/index.js +2 -2
  36. package/lib/init/template/github-actions/files/kyma-setup/action.yaml +0 -2
  37. package/lib/init/template/github-actions/index.js +3 -3
  38. package/lib/init/template/hana/index.js +19 -22
  39. package/lib/init/template/helm/index.js +47 -50
  40. package/lib/init/template/html5-repo/files/containerize.yaml.hbs +0 -10
  41. package/lib/init/template/html5-repo/files/mta.yaml.hbs +3 -7
  42. package/lib/init/template/html5-repo/files/values.yaml.hbs +6 -0
  43. package/lib/init/template/html5-repo/files/xs-app.json.hbs +5 -3
  44. package/lib/init/template/html5-repo/index.js +10 -8
  45. package/lib/init/template/http/index.js +31 -10
  46. package/lib/init/template/ias/files/mta.yaml.hbs +3 -0
  47. package/lib/init/template/ias/files/values.yaml.hbs +4 -1
  48. package/lib/init/template/ias/index.js +10 -11
  49. package/lib/init/template/kafka/index.js +3 -3
  50. package/lib/init/template/local-messaging/index.js +2 -2
  51. package/lib/init/template/malware-scanner/index.js +3 -7
  52. package/lib/init/template/mta/files/mta.yaml.hbs +10 -0
  53. package/lib/init/template/multitenancy/index.js +8 -10
  54. package/lib/init/template/notifications/index.js +2 -2
  55. package/lib/init/template/pipeline/index.js +5 -1
  56. package/lib/init/template/portal/files/mta.yaml.hbs +6 -0
  57. package/lib/init/template/portal/index.js +7 -7
  58. package/lib/init/template/postgres/index.js +4 -4
  59. package/lib/init/template/redis/index.js +2 -2
  60. package/lib/init/template/redis-messaging/index.js +2 -2
  61. package/lib/init/template/sample/files/app/admin-books/fiori-service.cds +2 -2
  62. package/lib/init/template/sample/files/javascript/admin-service.js.hbs +24 -0
  63. package/lib/init/template/sample/files/javascript/cat-service.js.hbs +43 -0
  64. package/lib/init/template/sample/files/typescript/admin-service.ts.hbs +16 -0
  65. package/lib/init/template/sample/files/typescript/cat-service.ts.hbs +31 -0
  66. package/lib/init/template/test/files/test/test.xs.hbs +1 -1
  67. package/lib/init/template/test/index.js +2 -2
  68. package/lib/init/template/tiny-sample/index.js +1 -1
  69. package/lib/init/template/workzone-standard/index.js +5 -6
  70. package/lib/init/template/xsuaa/files/mta.yaml.hbs +0 -2
  71. package/lib/init/template/xsuaa/index.js +24 -19
  72. package/lib/lint/eslintHelp.json +1 -1
  73. package/lib/util/question.js +1 -1
  74. package/npm-shrinkwrap.json +22 -22
  75. package/package.json +1 -1
@@ -24,26 +24,22 @@ module.exports = class DestinationTemplate extends require('../../plugin') {
24
24
 
25
25
  async combine() {
26
26
  const project = readProject()
27
- const { hasHelm, hasApprouter, hasMultitenancy, hasHelmUnifiedRuntime, hasMta, srvPath, isJava } = project
27
+ const { addHelm, addApprouter, addMultitenancy, addHelmUnifiedRuntime, addMta, hasMta, srvPath, isJava } = project
28
28
 
29
- if (hasMultitenancy) {
30
- await merge({ cds: { requires: { destinations:true } } }).into('mtx/sidecar/package.json')
31
- }
32
-
33
- if (hasMta) {
29
+ if (addMta || (addApprouter || addMultitenancy) && hasMta) {
34
30
  const srv = srv4(srvPath)
35
31
  const additions = [srv, destination]
36
32
  const relationships = [{
37
33
  insert: [destination, 'name'],
38
34
  into: [srv, 'requires', 'name']
39
35
  }]
40
- if (hasApprouter) {
36
+ if (addApprouter) {
41
37
  relationships.push({
42
38
  insert: [destination, 'name'],
43
39
  into: [approuter, 'requires', 'name']
44
40
  })
45
41
  }
46
- if (hasMultitenancy) {
42
+ if (addMultitenancy) {
47
43
  relationships.push({
48
44
  insert: [destination, 'name'],
49
45
  into: [mtxSidecar4(isJava ? 'mtx/sidecar' : 'gen/mtx/sidecar'), 'requires', 'name']
@@ -52,7 +48,7 @@ module.exports = class DestinationTemplate extends require('../../plugin') {
52
48
  await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', { with: project, additions, relationships })
53
49
  }
54
50
 
55
- if (hasHelm || hasHelmUnifiedRuntime) {
51
+ if (addHelm || addHelmUnifiedRuntime) {
56
52
  await merge(__dirname, 'files/values.yaml').into('chart/values.yaml')
57
53
  }
58
54
  }
@@ -24,9 +24,9 @@ module.exports = class extends require('../../plugin') {
24
24
 
25
25
  async combine() {
26
26
  const project = readProject()
27
- const { appName, hasMta, hasHelm, hasHelmUnifiedRuntime, isJava, hasMultitenancy, srvPath } = project
27
+ const { appName, addMta, addHelm, addHelmUnifiedRuntime, isJava, addMultitenancy, srvPath } = project
28
28
 
29
- if (hasMta) {
29
+ if (addMta || addMultitenancy) {
30
30
  const dynatrace = {
31
31
  in: 'resources',
32
32
  where: {
@@ -34,13 +34,16 @@ module.exports = class extends require('../../plugin') {
34
34
  'parameters.service': 'dynatrace'
35
35
  }
36
36
  }
37
- const srv = srv4(srvPath)
38
- const additions = [srv, dynatrace]
39
- const relationships = [{
40
- insert: [dynatrace, 'name'],
41
- into: [srv, 'requires', 'name']
42
- }]
43
- if (hasMultitenancy) {
37
+ const additions = [dynatrace], relationships = []
38
+ if (addMta) {
39
+ const srv = srv4(srvPath)
40
+ additions.push(srv)
41
+ relationships.push({
42
+ insert: [dynatrace, 'name'],
43
+ into: [srv, 'requires', 'name']
44
+ })
45
+ }
46
+ if (addMultitenancy) {
44
47
  const mtxSidecar = mtxSidecar4(isJava ? 'mtx/sidecar' : 'gen/mtx/sidecar')
45
48
  additions.push(mtxSidecar)
46
49
  relationships.push({
@@ -54,7 +57,7 @@ module.exports = class extends require('../../plugin') {
54
57
  })
55
58
  }
56
59
 
57
- if (hasHelm || hasHelmUnifiedRuntime) {
60
+ if (addHelm || addHelmUnifiedRuntime) {
58
61
  await merge(__dirname, 'files', 'values.yaml').into('chart/values.yaml')
59
62
  }
60
63
  }
@@ -41,9 +41,9 @@ module.exports = class EnterpriseMessagingTemplate extends require('../../plugin
41
41
 
42
42
  async combine() {
43
43
  const project = readProject()
44
- const { hasXsuaa, hasHelm, hasHelmUnifiedRuntime, hasMta, srvPath, appName } = project
44
+ const { addXsuaa, addHelm, addHelmUnifiedRuntime, addMta, srvPath, appName } = project
45
45
 
46
- if (hasMta) {
46
+ if (addMta) {
47
47
  const srv = srv4(srvPath)
48
48
  await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', {
49
49
  project,
@@ -55,8 +55,8 @@ module.exports = class EnterpriseMessagingTemplate extends require('../../plugin
55
55
  })
56
56
  }
57
57
 
58
- if (hasXsuaa) {
59
- if (hasMta) {
58
+ if (addXsuaa || addMta) {
59
+ if (addMta) {
60
60
  await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', {
61
61
  project,
62
62
  additions: [xsuaa]
@@ -72,7 +72,7 @@ module.exports = class EnterpriseMessagingTemplate extends require('../../plugin
72
72
  })
73
73
  }
74
74
 
75
- if (hasHelm || hasHelmUnifiedRuntime) {
75
+ if (addHelm || addHelmUnifiedRuntime) {
76
76
  await merge(__dirname, 'files', 'values.yaml').into('chart/values.yaml')
77
77
  }
78
78
 
@@ -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 = typeof (await read(configFile)).cds?.requires?.messaging !== 'object'
37
+ project.shortcut = !exists(configFile) || 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
  }
@@ -42,9 +42,9 @@ module.exports = class EnterpriseMessagingSharedTemplate extends require('../../
42
42
 
43
43
  async combine() {
44
44
  const project = readProject()
45
- const { hasMta, hasHelm, hasHelmUnifiedRuntime, srvPath } = project
45
+ const { addMta, addHelm, addHelmUnifiedRuntime, srvPath } = project
46
46
 
47
- if (hasMta) {
47
+ if (addMta) {
48
48
  const srv = srv4(srvPath)
49
49
  await merge(__dirname, 'files', 'mta.yaml.hbs').into('mta.yaml', {
50
50
  project,
@@ -56,7 +56,7 @@ module.exports = class EnterpriseMessagingSharedTemplate extends require('../../
56
56
  })
57
57
  }
58
58
 
59
- if (hasHelm || hasHelmUnifiedRuntime) {
59
+ if (addHelm || addHelmUnifiedRuntime) {
60
60
  await merge(__dirname, 'files/values.yaml').into('chart/values.yaml')
61
61
  }
62
62
 
@@ -26,8 +26,8 @@ module.exports = class ExtensibilityTemplate extends require('../../plugin') {
26
26
 
27
27
  async combine() {
28
28
  const project = readProject()
29
- const { hasXsuaa } = project
30
- if (hasXsuaa) {
29
+ const { addXsuaa } = project
30
+ if (addXsuaa) {
31
31
  await merge(__dirname, 'files', 'xs-security.json.hbs').into('xs-security.json', {
32
32
  project,
33
33
  additions: [
@@ -1,4 +1,4 @@
1
- const cds = require('../../../cds'), { read } = cds.utils
1
+ const cds = require('../../../cds'), { exists, read } = cds.utils
2
2
  const { readProject } = require('../../projectReader')
3
3
  const { merge } = require('../../merge')
4
4
 
@@ -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 = typeof (await read(configFile)).cds?.requires?.messaging !== 'object'
24
+ project.shortcut = !exists(configFile) || 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
  }
@@ -45,8 +45,6 @@ runs:
45
45
  shell: bash
46
46
  - run: curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
47
47
  shell: bash
48
- - run: npm install -g ctz
49
- shell: bash
50
48
  - shell: bash
51
49
  run: |
52
50
  mkdir ${HOME}/kyma-binaries
@@ -50,9 +50,9 @@ module.exports = class GitHubActionTemplate extends require('../../plugin') {
50
50
 
51
51
  async combine() {
52
52
  const project = readProject()
53
- const { hasMta, hasHelm } = project, { force } = cds.cli.options
53
+ const { addMta, addHelm } = project, { force } = cds.cli.options
54
54
  project.sap = cds.cli.options.sap
55
- if (hasMta) {
55
+ if (addMta) {
56
56
  const cf = '.github/workflows/cf.yaml'
57
57
  if (force || !exists(cf)) {
58
58
  await renderAndCopy(path.join(__dirname, 'files/workflows/cf.yaml.hbs'), cf, project)
@@ -62,7 +62,7 @@ module.exports = class GitHubActionTemplate extends require('../../plugin') {
62
62
  await copy(path.join(__dirname, 'files/cf-setup'), cfSetup)
63
63
  }
64
64
  }
65
- if (hasHelm) {
65
+ if (addHelm) {
66
66
  const kyma = '.github/workflows/kyma.yaml'
67
67
  if (force || !exists(kyma)) {
68
68
  await renderAndCopy(path.join(__dirname, 'files/workflows/kyma.yaml.hbs'), kyma, project)
@@ -1,6 +1,6 @@
1
1
  const { join } = require('path')
2
2
  const cds = require('../../../cds')
3
- const { read, write, exists, copy, rimraf } = cds.utils
3
+ const { read, write, exists, copy } = cds.utils
4
4
  const { readProject } = require('../../projectReader')
5
5
  const { merge, sort } = require('../../merge')
6
6
  const mvn = require('../../mvn')
@@ -21,7 +21,7 @@ module.exports = class HanaTemplate extends require('../../plugin') {
21
21
  async run() {
22
22
  const project = readProject()
23
23
  const { isJava, configFile, db } = project
24
- project.shortcut = typeof (await read(configFile)).cds?.requires?.db !== 'object'
24
+ project.shortcut = !exists(configFile) || typeof (await read(configFile)).cds?.requires?.db !== 'object'
25
25
 
26
26
  // REVISIT: Let cds build generate those by default
27
27
  await merge(__dirname, 'files/src/.hdiconfig').into(join(db.folder, 'src/.hdiconfig'))
@@ -44,9 +44,9 @@ module.exports = class HanaTemplate extends require('../../plugin') {
44
44
 
45
45
  async combine() {
46
46
  const project = readProject()
47
- const { hasMta, hasHelm, hasHelmUnifiedRuntime, hasHtml5Repo, hasContainerize, isJava, hasMultitenancy, srvPath } = project
47
+ const { addMta, hasMta, addHelm, addHelmUnifiedRuntime, addMultitenancy, addContainerize, isJava, hasHelm, hasHelmUnifiedRuntime, hasMultitenancy, srvPath } = project
48
48
 
49
- if (hasMta) {
49
+ if (addMta || (addMultitenancy && hasMta)) {
50
50
  const srv = srv4(srvPath)
51
51
  const db = hasMultitenancy ? serviceManager : hdiContainer
52
52
  const deletions = hasMultitenancy ? [{
@@ -86,26 +86,23 @@ module.exports = class HanaTemplate extends require('../../plugin') {
86
86
  })
87
87
  }
88
88
 
89
- if (hasHelm || hasHelmUnifiedRuntime) {
90
- if (hasMultitenancy) {
91
- await merge('chart/values.yaml')
92
- .remove(['hana-deployer', 'srv.bindings.db', 'hana'])
93
-
94
- await merge('chart/Chart.yaml')
95
- .remove([
96
- { dependencies: { alias: 'hana' } },
97
- { dependencies: { alias: 'hana-deployer' } }
98
- ])
99
-
100
- if (!hasHtml5Repo) {
101
- await rimraf('chart/charts/content-deployment') // REVISIT: Move to build task
102
- }
103
- } else {
104
- await merge(__dirname, 'files', 'values.yaml.hbs').into('chart/values.yaml', { with: project })
105
- }
89
+ if (!hasMultitenancy && (addHelm || addHelmUnifiedRuntime)) {
90
+ await merge(__dirname, 'files', 'values.yaml.hbs').into('chart/values.yaml', { with: project })
91
+
92
+ }
93
+
94
+ if (addMultitenancy && (hasHelm || hasHelmUnifiedRuntime)) {
95
+ await merge('chart/values.yaml')
96
+ .remove(['hana-deployer', 'srv.bindings.db', 'hana'])
97
+
98
+ await merge('chart/Chart.yaml')
99
+ .remove([
100
+ { dependencies: { alias: 'hana' } },
101
+ { dependencies: { alias: 'hana-deployer' } }
102
+ ])
106
103
  }
107
104
 
108
- if (hasContainerize && !hasMultitenancy) {
105
+ if (addContainerize && !hasMultitenancy) {
109
106
  const additions = [{
110
107
  in: 'modules',
111
108
  where: { name: `${project.appName}-hana-deployer` }
@@ -1,7 +1,6 @@
1
1
  const { join } = require('path')
2
- const yaml = require('yaml')
3
2
  const cds = require('../../../cds')
4
- const { exists, rimraf, copy, readFileSync } = cds.utils
3
+ const { readFileSync, exists, rimraf, copy, yaml } = cds.utils
5
4
  const { readProject } = require('../../projectReader')
6
5
  const { merge } = require('../../merge')
7
6
  const { ask4 } = require('../../../util/question')
@@ -37,47 +36,36 @@ module.exports = class HelmTemplate extends require('../../plugin') {
37
36
  // Won't need this any more with plugin approach: package not there -> plugin not pulled
38
37
  static hasInProduction() {
39
38
  if (exists('chart/Chart.yaml')) {
40
- const chartFile = readFileSync(join(cds.root, 'chart', 'Chart.yaml'), 'utf8')
41
- const chartYaml = yaml.parseDocument(chartFile).toJS()
39
+ const chartYaml = yaml.parse(readFileSync(join(cds.root, 'chart', 'Chart.yaml'), 'utf8'))
42
40
  return chartYaml.annotations?.["app.kubernetes.io/managed-by"] === 'cds-dk/helm'
43
- }
44
- return false
41
+ }
42
+ return false
45
43
  }
46
44
 
47
45
  async run() {
48
46
  const project = readProject()
49
- project.domain = 'abc.com'
50
- project.registry = 'registry-server'
51
- project.imagePullSecret = 'docker-registry'
52
- project.tag = 'latest'
53
-
54
- if (cds.cli.command === 'add' && !HelmTemplate.hasInProduction()) {
55
- let registry = 'registry-server', tag = 'latest', domain = 'abc.com'
56
-
47
+ let imagePullSecret, registry, domain, tag
48
+ if (!HelmTemplate.hasInProduction() && !project.isBas /* don't run this for the BAS Yeoman generator */) {
57
49
  try {
58
50
  const domainGuess = execSync(`kubectl config view --minify --output jsonpath="{.clusters[*].cluster.server}"`, { stdio: "pipe" }).toString()
59
51
  const domainStartIndex = domainGuess.indexOf('api.')
60
52
  if (domainStartIndex !== -1) domain = domainGuess.substring(domainStartIndex + 4)
61
53
  } catch (error) { /* ignore */ }
62
54
 
63
- // read project.registry
64
55
  if (exists('containerize.yaml')) {
65
- const containerizeYamlFile = readFileSync(join(cds.root, 'containerize.yaml'), 'utf8')
66
- const containerizeYaml = yaml.parseDocument(containerizeYamlFile).toJS()
67
- registry = containerizeYaml.repository
68
- tag = containerizeYaml.tag
56
+ const { repository: r, tag: t } = yaml.parse(join(cds.root, 'containerize.yaml'))
57
+ if (r) registry = r
58
+ if (t) tag = t
69
59
  }
70
-
71
- if (!cds.cli.options['y']) {
72
- const [registryAns] = await ask4(`registry server (${registry}): `)
73
- registry = registryAns || registry
60
+ if (!cds.cli.options.y && !cds.cli.options.force) {
61
+ registry ??= await ask4(`registry server: `)
62
+ domain ??= await ask4(`cluster domain: `)
74
63
  }
75
-
76
- project.domain = domain
77
- project.registry = registry
78
- project.tag = tag
79
64
  }
80
-
65
+ project.registry = registry ?? '<registry-server>'
66
+ project.domain = domain ?? '<cluster-domain>'
67
+ project.imagePullSecret = imagePullSecret ?? 'docker-registry'
68
+ project.tag = tag ?? 'latest'
81
69
  await copy(join(__dirname, 'files', 'values.schema.json')).to('chart/values.schema.json')
82
70
  await merge(__dirname, 'files/Chart.yaml.hbs').into('chart/Chart.yaml', { with: project })
83
71
  await merge(__dirname, 'files/values.yaml.hbs').into('chart/values.yaml', { with: project })
@@ -87,40 +75,49 @@ module.exports = class HelmTemplate extends require('../../plugin') {
87
75
 
88
76
  async combine() {
89
77
  // REVISIT: This must be moved to the respective plugins
90
- const { hasDestination, hasEnterpriseMessaging, hasEnterpriseMessagingShared, hasHana, hasMultitenancy, hasXsuaa, hasHtml5Repo, hasApprouter, hasKafka, hasAttachments, hasPortal, hasMalwareScanner, hasDynatrace, hasCloudLogging, hasAuditLogging } = readProject()
91
-
92
- if (hasApprouter) {
78
+ const {
79
+ addHana, addMultitenancy, addXsuaa,
80
+ addApprouter, addIas, addAms, hasXsuaa, hasMultitenancy,
81
+ addDestination, addEnterpriseMessaging, addEnterpriseMessagingShared, addHtml5Repo, hasHtml5Repo, addKafka, addAttachments, addPortal, addMalwareScanner,
82
+ addDynatrace, addCloudLogging, addAuditLogging,
83
+ } = readProject()
84
+
85
+ if (addApprouter) {
93
86
  await this._mergeDependency('web-application', 'approuter')
94
87
  }
95
88
 
96
- if (hasHtml5Repo) {
97
- await this._mergeDependency('service-instance', 'html5-apps-repo-host')
98
- await this._mergeDependency('content-deployment', 'html5-apps-deployer')
99
- if (hasApprouter) {
89
+ if (addHtml5Repo || addApprouter && hasHtml5Repo) {
90
+ if (addHtml5Repo) {
91
+ await this._mergeDependency('service-instance', 'html5-apps-repo-host')
92
+ await this._mergeDependency('content-deployment', 'html5-apps-deployer')
93
+ }
94
+ if (addApprouter) {
100
95
  await this._mergeDependency('service-instance', 'html5-apps-repo-runtime')
101
96
  }
102
97
  }
103
- if (hasMultitenancy) {
104
- await this._mergeDependency('web-application', 'sidecar')
105
- if (hasXsuaa) {
98
+ if (addMultitenancy || addXsuaa || addIas || addAms) {
99
+ if (addMultitenancy) {
100
+ await this._mergeDependency('web-application', 'sidecar')
101
+ }
102
+ if (hasXsuaa && hasMultitenancy) {
106
103
  await this._mergeDependency('service-instance', 'saas-registry')
107
- } else {
104
+ } else if (hasMultitenancy) {
108
105
  await this._mergeDependency('service-instance', 'subscription-manager')
109
106
  }
110
107
  }
111
- if (hasDestination) {
108
+ if (addDestination) {
112
109
  await this._mergeDependency('service-instance', 'destination')
113
110
  }
114
- if (hasAttachments) {
111
+ if (addAttachments) {
115
112
  await this._mergeDependency('service-instance', 'attachments')
116
113
  }
117
- if (hasEnterpriseMessaging || hasEnterpriseMessagingShared) {
114
+ if (addEnterpriseMessaging || addEnterpriseMessagingShared) {
118
115
  await this._mergeDependency('service-instance', 'event-mesh')
119
116
  }
120
- if (hasXsuaa) {
117
+ if (addXsuaa) {
121
118
  await this._mergeDependency('service-instance', 'xsuaa')
122
119
  }
123
- if (hasHana) {
120
+ if (addHana || addMultitenancy) {
124
121
  if (hasMultitenancy) {
125
122
  await this._mergeDependency('service-instance', 'service-manager')
126
123
  } else {
@@ -128,23 +125,23 @@ module.exports = class HelmTemplate extends require('../../plugin') {
128
125
  await this._mergeDependency('content-deployment', 'hana-deployer')
129
126
  }
130
127
  }
131
- if (hasKafka) {
128
+ if (addKafka) {
132
129
  await this._mergeDependency('service-instance', 'kafka')
133
130
  }
134
- if (hasPortal) {
131
+ if (addPortal) {
135
132
  await this._mergeDependency('service-instance', 'portal')
136
133
  await this._mergeDependency('content-deployment', 'portal-deployer')
137
134
  }
138
- if (hasMalwareScanner) {
135
+ if (addMalwareScanner) {
139
136
  await this._mergeDependency('service-instance', 'malware-scanner')
140
137
  }
141
- if (hasCloudLogging) {
138
+ if (addCloudLogging) {
142
139
  await this._mergeDependency('service-instance', 'cloud-logging')
143
140
  }
144
- if (hasDynatrace) {
141
+ if (addDynatrace) {
145
142
  await this._mergeDependency('service-instance', 'dynatrace')
146
143
  }
147
- if (hasAuditLogging) {
144
+ if (addAuditLogging) {
148
145
  await this._mergeDependency('service-instance', 'auditlog')
149
146
  }
150
147
  }
@@ -1,14 +1,4 @@
1
1
  ---
2
- before-all:
3
- {{#hasUI5}}
4
- - mkdir -p app/html5-deployer/resources
5
- {{#apps}}
6
- - npm i --prefix app/{{app}}
7
- - npm run build --prefix app/{{app}}
8
- # zip filename should match the archiveName specified in ui5-deploy.yaml
9
- - cp -f app/{{app}}/dist/{{app}}.zip app/html5-deployer/resources/{{app}}.zip
10
- {{/apps}}
11
- {{/hasUI5}}
12
2
  modules:
13
3
  - name: {{appName}}-html5-deployer
14
4
  build-parameters:
@@ -28,13 +28,6 @@ modules:
28
28
  {{#hasXsuaa}}
29
29
  - name: {{appName}}-auth
30
30
  {{/hasXsuaa}}
31
- {{#hasIas}}
32
- - name: {{appName}}-ias
33
- parameters:
34
- config:
35
- credential-type: X509_GENERATED
36
- app-identifier: app-deployer
37
- {{/hasIas}}
38
31
  - name: srv-api
39
32
  - name: {{appName}}-html5-repo-host
40
33
  parameters:
@@ -52,6 +45,7 @@ modules:
52
45
  target-path: {{#isNodejs}}{{& appPath }}{{/isNodejs}}{{#isJava}}resources{{/isJava}}
53
46
  {{/apps}}
54
47
  {{#hasWorkzoneStandard}}
48
+ {{#hasMultitenancy}}
55
49
  parameters:
56
50
  config:
57
51
  HTML5Runtime_enabled: true
@@ -66,11 +60,13 @@ modules:
66
60
  ProxyType: Internet
67
61
  HTML5.ForwardAuthToken: true
68
62
  HTML5.DynamicDestination: true
63
+ {{#hasIas}}HTML5.IASDependencyName: {{appName}}-ias-api{{/hasIas}}
69
64
  - Name: ui5
70
65
  URL: https://ui5.sap.com
71
66
  Authentication: NoAuthentication
72
67
  Type: HTTP
73
68
  ProxyType: Internet
69
+ {{/hasMultitenancy}}
74
70
  {{/hasWorkzoneStandard}}
75
71
 
76
72
  {{#apps}}
@@ -53,3 +53,9 @@ approuter:
53
53
  html5-apps-repo-runtime:
54
54
  serviceInstanceName: html5-apps-repo-runtime
55
55
  {{/hasApprouter}}
56
+ {{#hasMultitenancy}}
57
+ sidecar:
58
+ bindings:
59
+ html5-apps-repo-host:
60
+ serviceInstanceName: html5-apps-repo-host
61
+ {{/hasMultitenancy}}
@@ -7,13 +7,15 @@
7
7
  "target": "/odata/$1",
8
8
  "destination": "srv-api",
9
9
  {{#hasXsuaa}}"authenticationType": "xsuaa",{{/hasXsuaa}}
10
+ {{#hasIas}}"authenticationType": "ias",{{/hasIas}}
10
11
  "csrfProtection": true
11
12
  },
12
13
  {
13
14
  "source": "^(.*)$",
14
- "target": "$1",
15
- "service": "html5-apps-repo-rt"{{#hasXsuaa}},
16
- "authenticationType": "xsuaa"{{/hasXsuaa}}
15
+ "service": "html5-apps-repo-rt",
16
+ {{#hasXsuaa}}"authenticationType": "xsuaa",{{/hasXsuaa}}
17
+ {{#hasIas}}"authenticationType": "ias",{{/hasIas}}
18
+ "target": "$1"
17
19
  }
18
20
  ]
19
21
  }
@@ -2,7 +2,7 @@ const { join } = require('path')
2
2
  const { readProject } = require('../../projectReader')
3
3
  const { merge } = require('../../merge')
4
4
  const { srv4, html5RepoHost, html5Runtime, xsuaa, appDeployer, approuter, mtxSidecar4 } = require('../../registries/mta')
5
- const { odataApi } = require('../../registries/xs-app')
5
+ const { odataApi, html5RepoApi } = require('../../registries/xs-app')
6
6
  const { exists } = require('../../../cds').utils
7
7
  const { renderAndCopy } = require('../../template')
8
8
 
@@ -37,14 +37,14 @@ module.exports = class Html5RepoTemplate extends require('../../plugin') {
37
37
  const project = readProject()
38
38
  const {
39
39
  isJava, srvPath, appPath, apps,
40
- hasApprouter, hasContainerize, hasMultitenancy, hasWorkzoneStandard,
41
- hasMta, hasXsuaa, hasHelm, hasHelmUnifiedRuntime, hasUI5
40
+ hasApprouter, addApprouter, addContainerize, addMultitenancy, addWorkzoneStandard,
41
+ addSample, hasMta, addMta, hasXsuaa, hasMultitenancy, hasWorkzoneStandard, addHelm, addHelmUnifiedRuntime, hasUI5
42
42
  } = project
43
43
 
44
44
  await Promise.all(apps.map(async ({ app }) => {
45
45
  project.app = app
46
46
  project.hasIndexHtml = exists(join(appPath, app, 'webapp/index.html'))
47
- const additions = [odataApi]
47
+ const additions = [odataApi, html5RepoApi]
48
48
  await merge(__dirname, 'files/xs-app.json.hbs').into(join(appPath, app, 'xs-app.json'), { with: project, additions })
49
49
  await merge(__dirname, 'files/app-package.json.hbs').into(join(appPath, app, 'package.json'), { project })
50
50
  }))
@@ -65,11 +65,11 @@ module.exports = class Html5RepoTemplate extends require('../../plugin') {
65
65
  }
66
66
  }
67
67
 
68
- if (hasMultitenancy) {
68
+ if (addMultitenancy) {
69
69
  await merge({ cds: { requires: { 'html5-repo': true } } }).into('mtx/sidecar/package.json')
70
70
  }
71
71
 
72
- if (hasMta) {
72
+ if (addMta || (addApprouter || addWorkzoneStandard || addMultitenancy || addSample) && hasMta) {
73
73
  const srv = srv4(srvPath)
74
74
  project.apps = apps
75
75
  const relationships = [{
@@ -114,14 +114,16 @@ module.exports = class Html5RepoTemplate extends require('../../plugin') {
114
114
  relationships
115
115
  })
116
116
  }
117
- if (hasContainerize) {
117
+
118
+ if (addContainerize) {
118
119
  const additions = [{
119
120
  in: 'modules',
120
121
  where: { name: `${project.appName}-html5-deployer` }
121
122
  }]
122
123
  await merge(__dirname, '/files/containerize.yaml.hbs').into('containerize.yaml', { with: project, additions })
123
124
  }
124
- if (hasHelm || hasHelmUnifiedRuntime) {
125
+
126
+ if (addHelm || addHelmUnifiedRuntime) {
125
127
  await renderAndCopy(join(__dirname, 'files/html5-deployer.package.json.hbs'), 'app/html5-deployer/package.json', project)
126
128
  await merge(__dirname, 'files/values.yaml.hbs').into('chart/values.yaml', { with: project })
127
129
  }
@@ -77,10 +77,40 @@ module.exports = class HttpTemplate extends require('../../plugin') {
77
77
  let entities = []
78
78
  let actions = []
79
79
 
80
+ const containedTargets = new Set()
81
+ for (const c of csn.childrenOf(s.name)) {
82
+ if (c.kind !== 'entity' || !c.elements) continue
83
+ for (const e of Object.values(c.elements)) {
84
+ if (e?.type !== 'cds.Composition' || !e.target) continue
85
+ const containment = Array.isArray(e.on) && e.on.some(t => t?.ref?.[0] === '$self')
86
+ if (!containment) continue
87
+ const target = csn.definitions?.[e.target] || csn.childrenOf(s.name).find(x => x.name === e.target)
88
+ const struct_key = Object.values(target?.keys || {}).some(k => k?.is_struct)
89
+ const struct_up = target?.elements?.up_?.is_struct === true
90
+ if (struct_key || struct_up) containedTargets.add(e.target)
91
+ }
92
+ }
93
+
94
+ const exposed = new Set((sInfo?.entities || []).map(e => e?.name || e).filter(Boolean))
80
95
  for (const c of csn.childrenOf(s.name)) {
81
96
  if (c.name.match(filterStringAsRegex(filter))) {
82
97
  if (c.name.includes('.texts')) continue
83
- c.kind === 'entity' ? entities.push(this.#addEntityInfo(c)) : c.kind === 'action' ? actions.push(c) : null
98
+ if (c.kind === 'entity') {
99
+ // Skip composition targets – they are not exposed as entity sets
100
+ if (containedTargets.has(c.name)) continue
101
+ if (exposed.size && !exposed.has(c.name)) continue
102
+ const autoexposed = c['@cds.autoexposed'] || c['@cds.autoexpose']
103
+ const valuelist = c['@cds.odata.valuelist'] === true
104
+ if (!exposed.size && autoexposed && !valuelist) continue
105
+ entities.push({
106
+ name: c.name,
107
+ readOnly: (c["@readonly"] || autoexposed || c['@odata.singleton']) ?? false,
108
+ isDraft: c['@odata.draft.enabled'] ?? false,
109
+ keys: c.keys
110
+ })
111
+ } else if (c.kind === 'action') {
112
+ actions.push(c)
113
+ }
84
114
  }
85
115
  }
86
116
  if (entities.length === 0 && actions.length === 0) return
@@ -96,15 +126,6 @@ module.exports = class HttpTemplate extends require('../../plugin') {
96
126
  return services
97
127
  }
98
128
 
99
- #addEntityInfo(e) {
100
- return {
101
- name: e.name,
102
- readOnly: (e["@readonly"] || e["@cds.autoexpose"] || e['@odata.singleton']) ?? false,
103
- isDraft: e['@odata.draft.enabled'] ?? false,
104
- keys: e.keys
105
- }
106
- }
107
-
108
129
  /**
109
130
  * @param {ServiceMap} services
110
131
  */