@sap/cds-dk 8.7.3 → 8.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/CHANGELOG.md +36 -1
  2. package/bin/bind.js +7 -8
  3. package/bin/cds.js +2 -4
  4. package/bin/compile/index.js +1 -0
  5. package/bin/deploy/index.js +10 -5
  6. package/bin/watch.js +48 -7
  7. package/lib/bind/{cfKeyProvider.js → cf.js} +43 -53
  8. package/lib/bind/k8s.js +138 -0
  9. package/lib/bind/plugin.js +48 -0
  10. package/lib/bind/shared.js +267 -0
  11. package/lib/build/buildTaskEngine.js +1 -1
  12. package/lib/build/plugins/helm/files/subcharts/content-deployment/Chart.yaml +0 -2
  13. package/lib/build/plugins/helm/files/subcharts/web-application/Chart.yaml +1 -3
  14. package/lib/build/plugins/helm/files/subcharts/web-application/templates/service-binding.yaml +3 -0
  15. package/lib/build/plugins/helm/files/subcharts/web-application/values.schema.json +3 -0
  16. package/lib/build/plugins/helm/files/subcharts/web-application/values.yaml +2 -1
  17. package/lib/build/util.js +1 -1
  18. package/lib/compile/to-mermaid.js +1 -2
  19. package/lib/deploy/to-hana/hana.js +1 -1
  20. package/lib/deploy/to-hana/mtaUtil.js +0 -13
  21. package/lib/env/schemas/cds-rc.js +17 -30
  22. package/lib/import/common.js +20 -10
  23. package/lib/init/constants.js +1 -1
  24. package/lib/init/merge.js +41 -32
  25. package/lib/init/projectReader.js +15 -7
  26. package/lib/init/registries/mta.js +7 -1
  27. package/lib/init/template/approuter/files/package.json +1 -1
  28. package/lib/init/template/approuter/files/xs-app.json.hbs +0 -11
  29. package/lib/init/template/cloud-logging/files/package.json.hbs +12 -1
  30. package/lib/init/template/cloud-logging/files/values.yaml.hbs +0 -2
  31. package/lib/init/template/cloud-logging/index.js +8 -15
  32. package/lib/init/template/destination/files/values.yaml +4 -4
  33. package/lib/init/template/destination/index.js +1 -1
  34. package/lib/init/template/html5-repo/files/app-package.json.hbs +0 -2
  35. package/lib/init/template/html5-repo/files/containerize.yaml.hbs +25 -0
  36. package/lib/init/template/html5-repo/files/mta.yaml.hbs +1 -2
  37. package/lib/init/template/html5-repo/files/package.json.hbs +1 -1
  38. package/lib/init/template/html5-repo/files/ui-resources/package.json.hbs +11 -0
  39. package/lib/init/template/html5-repo/files/ui5-deploy.yaml.hbs +4 -7
  40. package/lib/init/template/html5-repo/files/values.yaml.hbs +6 -4
  41. package/lib/init/template/html5-repo/index.js +22 -10
  42. package/lib/init/template/http/index.js +1 -1
  43. package/lib/init/template/lint/index.js +7 -1
  44. package/lib/init/template/multitenancy/files/mta.yaml.hbs +0 -2
  45. package/lib/init/template/multitenancy/index.js +1 -1
  46. package/lib/init/template/portal/files/mta.yaml.hbs +9 -0
  47. package/lib/init/template/portal/index.js +3 -1
  48. package/lib/init/template/sample/files/app/admin-books/webapp/manifest.json +119 -119
  49. package/lib/init/template/sample/files/app/browse/webapp/manifest.json +1 -1
  50. package/lib/init/template/telemetry/index.js +0 -13
  51. package/lib/init/template/typer/files/package.json +3 -0
  52. package/lib/init/template/workzone-standard/files/cdm.json.hbs +97 -0
  53. package/lib/init/template/workzone-standard/files/mta.yaml.hbs +23 -0
  54. package/lib/init/template/workzone-standard/index.js +70 -39
  55. package/lib/init/template/xsuaa/files/mta.yaml.hbs +2 -2
  56. package/lib/init/template/xsuaa/files/values.yaml.hbs +0 -2
  57. package/lib/init/template/xsuaa/index.js +22 -10
  58. package/lib/lint/io.js +8 -4
  59. package/lib/mtx/util/cf.js +1 -2
  60. package/lib/util/cf.js +104 -84
  61. package/lib/util/command.js +1 -2
  62. package/lib/util/git.js +1 -1
  63. package/npm-shrinkwrap.json +53 -45
  64. package/package.json +1 -1
  65. package/bin/deploy/to-cf.js +0 -0
  66. package/bin/deploy/via-mta.js +0 -0
  67. package/lib/bind/KubernetesApiAccessor.js +0 -81
  68. package/lib/bind/bindingManager.js +0 -89
  69. package/lib/bind/bindingResolver.js +0 -54
  70. package/lib/bind/bindingUtil.js +0 -129
  71. package/lib/bind/index.js +0 -127
  72. package/lib/bind/kubernetesCredentialsProvider.js +0 -84
  73. package/lib/bind/userCdsrcJsonStorageProvider.js +0 -92
  74. package/lib/init/template/destination/files/package.sidecar.json +0 -7
  75. package/lib/init/template/html5-repo/files/package.sidecar.json +0 -7
  76. package/lib/init/template/telemetry/files/package.json.hbs +0 -18
@@ -125,7 +125,9 @@ module.exports = new class ProjectReader {
125
125
  const _uiEmbedded = () => exists(join(env.folders.app, 'xs-app.json'))
126
126
  const _uiModule = () => !_uiEmbedded() && isdir(env.folders.app) && fs.readdirSync(resolve(cds.root, env.folders.app)).length > 0
127
127
  const _isJava = () => this.isJava
128
- const isApp = name => name !== 'appconfig' && !name.startsWith('_') && name !== 'router' && name !== 'portal'
128
+ const isApp = name => {
129
+ return name !== 'appconfig' && !name.startsWith('_') && name !== 'router' && name !== 'portal' && name !== 'workzone'
130
+ }
129
131
  const reserved = {
130
132
  dependencies: () => pkgJson().dependencies,
131
133
  has: x => _inProd(x),
@@ -152,7 +154,9 @@ module.exports = new class ProjectReader {
152
154
  },
153
155
  configFile: () => _isJava() ? '.cdsrc.json' : 'package.json',
154
156
  apps: () => {
155
- const apps = fs.readdirSync(path.resolve(cds.root, cds.env.folders.app)).filter(e =>
157
+ const appPath = path.resolve(cds.root, cds.env.folders.app)
158
+ if (!exists(appPath)) return []
159
+ const apps = fs.readdirSync(appPath).filter(e =>
156
160
  isdir(path.join(cds.root, cds.env.folders.app, e)) && isApp(e)
157
161
  )
158
162
  return apps.map((app, i) => {
@@ -164,14 +168,18 @@ module.exports = new class ProjectReader {
164
168
  return { app, strippedApp: app.replace(/-/g, ''), vizId, isNotLast: i < apps.length - 1, manifestAppId: manifest?.['sap.app']?.id ?? app}
165
169
  })
166
170
  },
167
- appUIPaths: () => (fs.readdirSync(path.resolve(cds.root, cds.env.folders.app))).filter(e =>
168
- isdir(join(cds.root, cds.env.folders.app, e)) && isApp(e)
169
- ),
171
+ appUIPaths: () => {
172
+ const appPath = path.resolve(cds.root, cds.env.folders.app)
173
+ if (!exists(appPath)) return []
174
+ return fs.readdirSync(appPath).filter(e =>
175
+ isdir(path.join(cds.root, cds.env.folders.app, e)) && isApp(e)
176
+ )
177
+ },
170
178
  hasIndexHtml: () => {},
171
179
  appPath: () => env.folders.app,
172
180
  appVersion: () => appVersion,
173
181
  jdkVersion: () => jdkVersion,
174
- approuterPath: () => _uiEmbedded() ? join(env.folders.app) : join(env.folders.app, 'router'),
182
+ approuterPath: () => (_uiEmbedded() ? join(env.folders.app) : join(env.folders.app, 'router')).replace(/\\/g, '/'),
175
183
  appName: () => appName,
176
184
  cleanedAppName: () => appName.replaceAll('_', '-'),
177
185
  strippedAppName: () => appName.replace(/-/g, ''),
@@ -210,7 +218,7 @@ module.exports = new class ProjectReader {
210
218
 
211
219
  /**
212
220
  * Finds and reads SpringBoot configuration in `cds.root/srv` dir.
213
- * This is done in a best-effort way. In no way can we replciate all of SpringBoot's
221
+ * This is done in a best-effort way. In no way can we replicate all of SpringBoot's
214
222
  * config variants.
215
223
  * @param {string[]?} roots array of directories to search for application.yaml, like `srv`
216
224
  * @returns {Promise<object[]>} array of objects with `cds` property
@@ -12,9 +12,14 @@ const approuter = { in: 'modules', where: { type: 'approuter.nodejs' } }
12
12
 
13
13
  const xsuaa = {
14
14
  in: 'resources',
15
- where: { type: 'org.cloudfoundry.managed-service', 'parameters.service': 'xsuaa' }
15
+ where: { type: 'org.cloudfoundry.managed-service', 'parameters.service': 'xsuaa', 'parameters.service-plan': 'application' }
16
16
  }
17
17
 
18
+ const xsuaa4 = plan => ({
19
+ in: 'resources',
20
+ where: { type: 'org.cloudfoundry.managed-service', 'parameters.service': 'xsuaa', 'parameters.service-plan': plan }
21
+ })
22
+
18
23
  const destination = {
19
24
  in: 'resources',
20
25
  where: { type: 'org.cloudfoundry.managed-service', 'parameters.service': 'destination' }
@@ -194,6 +199,7 @@ module.exports = {
194
199
  srv4,
195
200
  approuter,
196
201
  xsuaa,
202
+ xsuaa4,
197
203
  destination,
198
204
  destinations,
199
205
  destinationSideBySideExtensibility,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "approuter",
3
3
  "dependencies": {
4
- "@sap/approuter": "^18.0.0"
4
+ "@sap/approuter": "^19.0.0"
5
5
  },
6
6
  "engines": {
7
7
  "node": "^20"
@@ -17,17 +17,6 @@
17
17
  "authenticationType": "none"
18
18
  },
19
19
  {{/hasMTXRouteJava}}
20
- {
21
- "source": "^/app/(.*)$",
22
- "target": "$1",
23
- "localDir": ".",
24
- "cacheControl": "no-cache, no-store, must-revalidate"
25
- },
26
- {
27
- "source": "^/appconfig/",
28
- "localDir": ".",
29
- "cacheControl": "no-cache, no-store, must-revalidate"
30
- },
31
20
  {
32
21
  "source": "^/(.*)$",
33
22
  "target": "$1",
@@ -1,7 +1,18 @@
1
1
  {
2
+ "dependencies": {
3
+ "@cap-js/telemetry": ">=0",
4
+ "@grpc/grpc-js": "^1",
5
+ "@opentelemetry/exporter-trace-otlp-grpc": "^0",
6
+ "@opentelemetry/exporter-metrics-otlp-grpc": "^0",
7
+ "@opentelemetry/host-metrics": "^0"
8
+ },
2
9
  "cds": {
3
10
  "requires": {
4
- "cloud-logging": true
11
+ "[{{profile}}]": {
12
+ "telemetry": {
13
+ "kind": "to-cloud-logging"
14
+ }
15
+ }
5
16
  }
6
17
  }
7
18
  }
@@ -12,5 +12,3 @@ cloud-logging:
12
12
  parameters:
13
13
  ingest_otlp:
14
14
  enabled: true
15
-
16
-
@@ -7,14 +7,14 @@ 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?.['cloud-logging'];
10
+ return env.requires?.telemetry?.kind === 'to-cloud-logging'
11
11
  }
12
12
 
13
13
  options() {
14
14
  return {
15
15
  'plan': {
16
16
  type: 'string',
17
- help: `Override the service plan used for the MTA generation.`,
17
+ help: 'Specify the service plan.',
18
18
  },
19
19
  'with-telemetry': {
20
20
  type: 'boolean',
@@ -23,19 +23,13 @@ module.exports = class extends require('../../plugin') {
23
23
  }
24
24
  }
25
25
 
26
- async canRun() {
27
- return true
28
- }
29
-
30
- requires() {
31
- const project = readProject(), { hasTelemetry } = project
32
- if ((cds.cli.options['with-telemetry'] || hasTelemetry)) return ['telemetry']
33
- }
34
-
35
26
  async run() {
36
- const project = readProject();
37
- await merge(__dirname, 'files/package.json.hbs').into('package.json', { with: project })
38
- await sort('package.json', 'dependencies')
27
+ const project = readProject(), { hasTelemetry, isNodejs } = project
28
+ if (isNodejs && (cds.cli.options['with-telemetry'] || hasTelemetry)) {
29
+ project.profile ??= 'production'
30
+ await merge(__dirname, 'files/package.json.hbs').into('package.json', { with: project })
31
+ await sort('package.json', 'dependencies')
32
+ }
39
33
  }
40
34
 
41
35
  async combine() {
@@ -82,4 +76,3 @@ module.exports = class extends require('../../plugin') {
82
76
  }
83
77
  }
84
78
  }
85
-
@@ -1,9 +1,9 @@
1
1
  srv:
2
2
  bindings:
3
3
  destination:
4
- serviceInstanceName: 'destination'
4
+ serviceInstanceName: destination
5
5
  destination:
6
- serviceOfferingName: 'destination'
7
- servicePlanName: 'lite'
6
+ serviceOfferingName: destination
7
+ servicePlanName: lite
8
8
  parameters:
9
- version: '1.0.0'
9
+ version: 1.0.0
@@ -27,7 +27,7 @@ module.exports = class DestinationTemplate extends require('../../plugin') {
27
27
  const { hasHelm, hasApprouter, hasMultitenancy, hasHelmUnifiedRuntime, hasMta, srvPath, isJava } = project
28
28
 
29
29
  if (hasMultitenancy) {
30
- await merge(__dirname, 'files/package.sidecar.json').into('mtx/sidecar/package.json')
30
+ await merge({ cds: { requires: { destinations:true } } }).into('mtx/sidecar/package.json')
31
31
  }
32
32
 
33
33
  if (hasMta) {
@@ -8,13 +8,11 @@
8
8
  "start": "ui5 serve"
9
9
  },
10
10
  "devDependencies": {
11
- {{#hasWorkzoneStandard}}"@sap/ui5-builder-webide-extension": "^1.1.9",{{/hasWorkzoneStandard}}
12
11
  "@ui5/cli": "^4",
13
12
  "ui5-task-zipper": "^3"
14
13
  },
15
14
  "ui5": {
16
15
  "dependencies": [
17
- {{#hasWorkzoneStandard}}"@sap/ui5-builder-webide-extension",{{/hasWorkzoneStandard}}
18
16
  "ui5-task-zipper"
19
17
  ]
20
18
  }
@@ -0,0 +1,25 @@
1
+ ---
2
+ before-all:
3
+ {{#hasUI5}}
4
+ - mkdir -p ui-resources/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 ui-resources/resources/{{app}}.zip
10
+ {{/apps}}
11
+ {{/hasUI5}}
12
+ modules:
13
+ - name: {{appName}}-html5-deployer
14
+ build-parameters:
15
+ buildpack:
16
+ {{#hasHelmUnifiedRuntime}}
17
+ builder: proxy-unified-runtime-dmz.int.repositories.cloud.sap/builder/noble
18
+ {{/hasHelmUnifiedRuntime}}
19
+ {{^hasHelmUnifiedRuntime}}
20
+ type: nodejs
21
+ builder: builder-jammy-base
22
+ {{/hasHelmUnifiedRuntime}}
23
+ path: ui-resources
24
+ env:
25
+ BP_NODE_RUN_SCRIPTS: ""
@@ -16,6 +16,7 @@ modules:
16
16
  type: nodejs
17
17
  path: {{#isNodejs}}gen/{{/isNodejs}}mtx/sidecar
18
18
  requires:
19
+ - name: {{appName}}-html5-repo-host
19
20
  - name: {{appName}}-html5-runtime
20
21
 
21
22
  - name: {{appName}}-app-deployer
@@ -49,13 +50,11 @@ modules:
49
50
  {{/apps}}
50
51
 
51
52
  resources:
52
- {{#hasApprouter}}
53
53
  - name: {{appName}}-html5-runtime
54
54
  type: org.cloudfoundry.managed-service
55
55
  parameters:
56
56
  service: html5-apps-repo
57
57
  service-plan: app-runtime
58
- {{/hasApprouter}}
59
58
 
60
59
  - name: {{appName}}-html5-repo-host
61
60
  type: org.cloudfoundry.managed-service
@@ -6,7 +6,7 @@
6
6
  {{#profile}}
7
7
  "[{{profile}}]": {
8
8
  {{/profile}}
9
- "html5-repo": true
9
+ "html5-runtime": true
10
10
  {{#profile}}
11
11
  }
12
12
  {{/profile}}
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "{{appName}}",
3
+ "version": "{{appVersion}}",
4
+ "description": "{{appDescription}}",
5
+ "scripts": {
6
+ "start": "node node_modules/@sap/html5-app-deployer/index.js"
7
+ },
8
+ "dependencies": {
9
+ "@sap/html5-app-deployer": "^7.0.0"
10
+ }
11
+ }
@@ -13,16 +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}}
23
16
  - name: ui5-task-zipper
24
17
  afterTask: generateVersionInfo
25
18
  configuration:
26
19
  archiveName: {{app}}
27
20
  additionalFiles:
28
21
  - xs-app.json
22
+ {{#isTypescript}}
23
+ - name: ui5-tooling-transpile-task
24
+ afterTask: replaceVersion
25
+ {{/isTypescript}}
@@ -4,9 +4,9 @@ html5-apps-repo-host:
4
4
  servicePlanName: app-host
5
5
  html5-apps-deployer:
6
6
  env:
7
- SAP_CLOUD_SERVICE: null
7
+ SAP_CLOUD_SERVICE: {{strippedAppName}}.service
8
8
  image:
9
- repository: "{{appName}}-html5-deployer"
9
+ repository: {{appName}}-html5-deployer
10
10
  bindings:
11
11
  xsuaa:
12
12
  serviceInstanceName: xsuaa
@@ -26,7 +26,9 @@ html5-apps-deployer:
26
26
  - configMapRef:
27
27
  name: "{{ .Release.Name }}-html5-apps-deployer-configmap"
28
28
  <%={{ }}=%>
29
- backendDestinations: {}
29
+ backendDestinations:
30
+ srv-api:
31
+ service: srv
30
32
  destination:
31
33
  parameters:
32
34
  HTML5Runtime_enabled: true
@@ -37,5 +39,5 @@ html5-apps-repo-runtime:
37
39
  approuter:
38
40
  bindings:
39
41
  html5-apps-repo-runtime:
40
- serviceInstanceName: 'html5-apps-repo-runtime'
42
+ serviceInstanceName: html5-apps-repo-runtime
41
43
  {{/hasApprouter}}
@@ -4,6 +4,7 @@ const { merge } = require('../../merge')
4
4
  const { srv4, html5RepoHost, html5Runtime, appDeployer, approuter, mtxSidecar4 } = require('../../registries/mta')
5
5
  const { odataApi } = require('../../registries/xs-app')
6
6
  const { exists } = require('../../../cds').utils
7
+ const { renderAndCopy } = require('../../template')
7
8
 
8
9
  module.exports = class Html5RepoTemplate extends require('../../plugin') {
9
10
 
@@ -17,7 +18,7 @@ module.exports = class Html5RepoTemplate extends require('../../plugin') {
17
18
  }
18
19
 
19
20
  static hasInProduction(env) {
20
- return !!env.requires['html5-repo']
21
+ return !!env.requires['html5-repo'] || !!env.requires['html5-runtime'] || !!env.requires['html5-host']
21
22
  }
22
23
 
23
24
  async run() {
@@ -44,15 +45,15 @@ module.exports = class Html5RepoTemplate extends require('../../plugin') {
44
45
  // app deployer requires a manifest.json
45
46
  await Promise.all(appUIPaths.map(p =>
46
47
  merge(__dirname, 'files/manifest.json')
47
- .into(join(appPath, p, 'webapp/manifest.json'), { project })
48
+ .into(join(appPath, p, 'webapp/manifest.json'), { project })
48
49
  ))
49
50
  }
50
51
 
51
52
  async combine() {
52
53
  const project = readProject()
53
- const { isJava, srvPath, appPath, hasMta, hasMultitenancy, hasHelm, hasHelmUnifiedRuntime, hasApprouter, apps } = project
54
+ const { isJava, srvPath, appPath, hasMta, hasMultitenancy, hasWorkzoneStandard, hasHelm, hasHelmUnifiedRuntime, hasApprouter, hasContainerize, apps } = project
54
55
 
55
- await Promise.all(apps.map(async ({app}) => {
56
+ await Promise.all(apps.map(async ({ app }) => {
56
57
  project.app = app
57
58
  project.hasIndexHtml = exists(join(appPath, app, 'webapp/index.html'))
58
59
  const additions = [odataApi]
@@ -60,13 +61,13 @@ module.exports = class Html5RepoTemplate extends require('../../plugin') {
60
61
  }))
61
62
 
62
63
  if (hasMultitenancy) {
63
- await merge(__dirname, 'files/package.sidecar.json').into('mtx/sidecar/package.json')
64
- }
64
+ await merge({ cds: { requires: { 'html5-runtime':true } } }).into('mtx/sidecar/package.json')
65
+ }
65
66
 
66
67
  if (hasMta) {
67
68
  const srv = srv4(srvPath)
68
69
  project.apps = apps
69
- const appModules = project.apps.map(app => ( {
70
+ const appModules = project.apps.map(app => ({
70
71
  in: 'modules',
71
72
  where: { type: 'html5', path: `${appPath}${app.app}` }
72
73
  }))
@@ -75,8 +76,11 @@ module.exports = class Html5RepoTemplate extends require('../../plugin') {
75
76
  insert: [html5RepoHost, 'name'],
76
77
  into: [appDeployer, 'requires', 'name'],
77
78
  }]
79
+ if (hasApprouter || hasWorkzoneStandard) {
80
+ additions.push(html5Runtime)
81
+ }
78
82
  if (hasApprouter) {
79
- additions.push(approuter, html5Runtime)
83
+ additions.push(approuter)
80
84
  relationships.push({
81
85
  insert: [html5Runtime, 'name'],
82
86
  into: [approuter, 'requires', 'name'],
@@ -88,13 +92,21 @@ module.exports = class Html5RepoTemplate extends require('../../plugin') {
88
92
  into: [mtxSidecar4(isJava ? 'mtx/sidecar' : 'gen/mtx/sidecar'), 'requires', 'name']
89
93
  })
90
94
  }
91
- await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', { with: project,
95
+ await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', {
96
+ with: project,
92
97
  additions,
93
98
  relationships
94
99
  })
95
100
  }
96
-
101
+ if (hasContainerize) {
102
+ const additions = [{
103
+ in: 'modules',
104
+ where: { name: `${project.appName}-html5-deployer` }
105
+ }]
106
+ await merge(__dirname, '/files/containerize.yaml.hbs').into('containerize.yaml', { with: project, additions })
107
+ }
97
108
  if (hasHelm || hasHelmUnifiedRuntime) {
109
+ await renderAndCopy(join(__dirname, 'files/ui-resources'), 'ui-resources', project)
98
110
  await merge(__dirname, 'files/values.yaml.hbs').into('chart/values.yaml', { with: project })
99
111
  }
100
112
  }
@@ -223,7 +223,7 @@ module.exports = class HttpTemplate extends require('../../plugin') {
223
223
  if (!this.approuterAuth) {
224
224
  const app = cds.cli.options['for-app']
225
225
  // Later: differentiate between CF and Kyma
226
- const env = await cf.getEnv(app)
226
+ const env = await cf.env(app)
227
227
  if (!cds.cli.options.dry) console.error('Fetching credentials from Cloud Foundry app \'' + app + '\'...')
228
228
  const hostname = `https://${env.application_env_json.VCAP_APPLICATION.application_uris[0]}`
229
229
  const { xsuaa, identity } = env.system_env_json.VCAP_SERVICES ?? {}
@@ -7,6 +7,7 @@ const io = require("../../../lint/io");
7
7
  const readline = require("readline");
8
8
  const { renderAndCopy } = require('../../template')
9
9
  const { LINT_DEV, LINT_GLOBAL } = require("../../constants").OPTIONS;
10
+ const { COMMAND_INIT } = require("../../constants");
10
11
  const cds = require("../../../cds");
11
12
  const { mkdirp, exists } = cds.utils;
12
13
  const IS_WIN = os.platform() === "win32";
@@ -101,6 +102,11 @@ module.exports = class LintTemplate extends require('../../plugin') {
101
102
  "names"
102
103
  ].join(" ")}`;
103
104
 
105
+ if (cds.cli.command === COMMAND_INIT) {
106
+ this._runTask(task + ' --package-lock-only');
107
+ return;
108
+ }
109
+
104
110
  if (cds.cli.options.force) {
105
111
  console.log(
106
112
  `\n\nAlmost done - installing ${this.missingNpmDependencies["names"].length} npm dependencies:\n${task}`
@@ -118,11 +124,11 @@ module.exports = class LintTemplate extends require('../../plugin') {
118
124
  console.log("\n");
119
125
  }
120
126
  });
127
+
121
128
  await this._promptInstallDependencies(task);
122
129
  }
123
130
  }
124
131
  }
125
-
126
132
  }
127
133
 
128
134
  _checkEslint() {
@@ -48,7 +48,6 @@ modules:
48
48
  []
49
49
 
50
50
  resources:
51
- {{#hasXsuaa}}
52
51
  - name: {{appName}}-registry
53
52
  type: org.cloudfoundry.managed-service
54
53
  requires:
@@ -80,7 +79,6 @@ resources:
80
79
  onUnSubscriptionAsync: true
81
80
  onUpdateDependenciesAsync: true
82
81
  callbackTimeoutMillis: 300000 # Increase if your deployments are taking longer than that
83
- {{/hasXsuaa}}
84
82
 
85
83
  {{#hasIas}}
86
84
  - name: {{appName}}-sms
@@ -35,7 +35,7 @@ module.exports = class MultitenancyTemplate extends require('../../plugin') {
35
35
  await mvn.add('mtx')
36
36
  }
37
37
  if (isNodejs) await sort('package.json', 'dependencies')
38
- await copyRenderedJSON(join(__dirname, 'files', 'package.sidecar.json.hbs'), join('mtx', 'sidecar', 'package.json'), project)
38
+ await copyRenderedJSON(join(__dirname, 'files', 'package.sidecar.json.hbs'), join('mtx', 'sidecar/package.json'), project)
39
39
  }
40
40
 
41
41
  async combine() {
@@ -17,6 +17,10 @@ modules:
17
17
  requires:
18
18
  - name: {{appName}}-portal
19
19
 
20
+ - name: {{appName}}-app-deployer
21
+ type: com.sap.application.content
22
+ path: {{#isNodejs}}gen{{/isNodejs}}{{#isJava}}.{{/isJava}}
23
+
20
24
  - name: {{appName}}-portal-deployer
21
25
  type: com.sap.application.content
22
26
  path: app/portal
@@ -46,6 +50,11 @@ resources:
46
50
  service: portal
47
51
  service-plan: standard
48
52
 
53
+ - name: {{appName}}-auth
54
+ type: org.cloudfoundry.managed-service
55
+ parameters:
56
+ service: xsuaa
57
+
49
58
  - name: {{appName}}-destination
50
59
  type: org.cloudfoundry.managed-service
51
60
  parameters:
@@ -37,7 +37,7 @@ module.exports = class PortalTemplate extends require('../../plugin') {
37
37
 
38
38
  if (hasMta) {
39
39
  const srv = srv4(srvPath)
40
- const additions = [srv, portal, portalDeployer]
40
+ const additions = [srv, portal, appDeployer, portalDeployer]
41
41
  const relationships = [{
42
42
  insert: [portal, 'name'],
43
43
  into: [portalDeployer, 'requires', 'name']
@@ -47,12 +47,14 @@ module.exports = class PortalTemplate extends require('../../plugin') {
47
47
  }]
48
48
 
49
49
  if (hasXsuaa) {
50
+ additions.push(xsuaa)
50
51
  relationships.push({
51
52
  insert: [xsuaa, 'name'],
52
53
  into: [portalDeployer, 'requires', 'name']
53
54
  })
54
55
  }
55
56
  if (hasHtml5Repo) {
57
+ additions.push(html5RepoHost)
56
58
  relationships.push({
57
59
  insert: [html5RepoHost, 'name'],
58
60
  into: [portalDeployer, 'requires', 'name']