@sap/cds-dk 4.7.3 → 4.8.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 (55) hide show
  1. package/CHANGELOG.md +22 -1
  2. package/bin/activate.js +5 -1
  3. package/bin/add.js +2 -2
  4. package/lib/client/activate.js +8 -3
  5. package/lib/client/base_command.js +5 -1
  6. package/lib/client/helper/cf_helper.js +5 -2
  7. package/lib/client/params.js +16 -2
  8. package/lib/client/settings_manager.js +15 -8
  9. package/lib/compile/openapi/csdl2openapi.js +6 -8
  10. package/lib/compile/to-xsuaa.js +0 -14
  11. package/lib/import/utils/MetadataConverter.js +6 -4
  12. package/lib/import/v2parser.js +59 -35
  13. package/lib/import/v4parser.js +70 -47
  14. package/lib/init/constants.js +9 -3
  15. package/lib/init/index.js +13 -7
  16. package/lib/init/template/_merging/existences.js +161 -0
  17. package/lib/init/template/approuter/files/default-env.json +9 -0
  18. package/lib/init/template/approuter/files/mta.yaml.hbs +48 -0
  19. package/lib/init/template/approuter/files/package.json +9 -0
  20. package/lib/init/template/approuter/files/xs-app.json +8 -0
  21. package/lib/init/template/approuter/index.js +66 -0
  22. package/lib/init/template/auditlog/files/dependencies.package.json +5 -0
  23. package/lib/init/template/auditlog/files/mta.yaml.hbs +13 -0
  24. package/lib/init/template/auditlog/index.js +38 -0
  25. package/lib/init/template/cf-manifest/index.js +1 -1
  26. package/lib/init/template/hana/files/mta.yaml.hbs +42 -0
  27. package/lib/init/template/hana/files/nodejs/dependencies.package.json +5 -0
  28. package/lib/init/template/hana/index.js +53 -24
  29. package/lib/init/template/java/index.js +1 -5
  30. package/lib/init/template/mta/files/mta.yaml.hbs +24 -220
  31. package/lib/init/template/mta/index.js +25 -17
  32. package/lib/init/template/mtx/files/cds.package.json +24 -0
  33. package/lib/init/template/mtx/files/dependencies.package.json +5 -0
  34. package/lib/init/template/mtx/files/mta.yaml.hbs +74 -0
  35. package/lib/init/template/mtx/files/xs-security.json.hbs +23 -9
  36. package/lib/init/template/mtx/index.js +126 -29
  37. package/lib/init/template/templateBase.js +14 -0
  38. package/lib/init/template/xsuaa/files/cds.package.json +9 -0
  39. package/lib/init/template/xsuaa/files/dependencies.package.json +6 -0
  40. package/lib/init/template/xsuaa/files/mta.yaml.hbs +17 -0
  41. package/lib/init/template/xsuaa/index.js +75 -0
  42. package/lib/init/util/fsUtil.js +17 -3
  43. package/lib/init/util/logger.js +3 -1
  44. package/lib/init/{template/mta → util}/projectReader.js +26 -11
  45. package/lib/init/util/templateUtil.js +267 -3
  46. package/lib/util/exec.d.ts +54 -0
  47. package/lib/util/exec.js +210 -0
  48. package/lib/watch/livereload-server.js +43 -31
  49. package/lib/watch/open.js +1 -1
  50. package/npm-shrinkwrap.json +4089 -15628
  51. package/package.json +7 -8
  52. package/readme.md +1 -1
  53. package/lib/import/internalDoc/edm2cdsTypeMapping.md +0 -38
  54. package/lib/init/template/mtx/package/cds.package.json +0 -29
  55. package/lib/init/template/mtx/package/dependencies.package.json +0 -9
@@ -1,6 +1,6 @@
1
1
  const path = require('path')
2
2
  const TemplateBase = require('../templateBase');
3
- const ProjectReader = require('../mta/projectReader')
3
+ const ProjectReader = require('../../util/projectReader');
4
4
 
5
5
  const { OPTION_CF_MANIFEST } = require('../../constants')
6
6
  const MANIFEST = 'manifest'
@@ -0,0 +1,42 @@
1
+ ---
2
+ modules:
3
+ - name: {{cap.appName}}-srv
4
+ type: {{cap.pLanguage}}
5
+ requires:
6
+ - name: {{cap.appName}}-db
7
+
8
+ {{^cap.isMultitenant}}
9
+ - name: {{cap.appName}}-db-deployer
10
+ type: hdb
11
+ path: {{& cap.db.0.path}}
12
+ parameters:
13
+ buildpack: nodejs_buildpack
14
+ requires:
15
+ - name: {{cap.appName}}-db
16
+ {{/cap.isMultitenant}}
17
+
18
+ {{#cap.hasRequires}}
19
+ resources:
20
+ {{#cap.requires}}
21
+ {{#resource.isHana}}
22
+ - name: {{cap.appName}}-db
23
+ {{#resource.isPlainHana}}
24
+ type: com.sap.xs.hdi-container
25
+ parameters:
26
+ service: {{resource.service}} # or 'hanatrial' on trial landscapes
27
+ {{/resource.isPlainHana}}
28
+ {{#resource.isManagedHana}} {{! enable automatic switching to 'hanatrial' on trial accounts}}
29
+ type: org.cloudfoundry.managed-service
30
+ parameters:
31
+ service: {{resource.service}}
32
+ {{/resource.isManagedHana}}
33
+ service-plan: {{resource.vcap.plan}}
34
+ {{#resource.vcap.name}}
35
+ service-name: {{resource.vcap.name}}
36
+ {{/resource.vcap.name}}
37
+ properties:
38
+ hdi-service-name: ${service-name}
39
+ {{/resource.isHana}}
40
+
41
+ {{/cap.requires}}
42
+ {{/cap.hasRequires}}
@@ -0,0 +1,5 @@
1
+ {
2
+ "dependencies": {
3
+ "hdb": "^0.18.3"
4
+ }
5
+ }
@@ -1,34 +1,22 @@
1
1
  const path = require('path');
2
2
 
3
+ const { fse } = require('@sap/cds-foss');
4
+
3
5
  const commandUtil = require('../../util/commandUtil');
4
6
  const mvnArchetypes = require('../../util/mvnArchetypeUtil');
5
7
  const term = require('../../../util/term');
8
+ const ProjectReader = require('../../util/projectReader');
6
9
 
7
10
  const TemplateBase = require('../templateBase');
8
11
 
9
12
  const { PROJECT_TYPE, OPTION_JAVA, KIND_SQL, URLS, KIND_HANA } = require('../../constants');
10
13
  const { nullLogger } = require('../../util/logger');
11
-
14
+ const { srvNode, srvJava, hdbDeployer, serviceManager, hdiContainer } = require('../_merging/existences');
12
15
 
13
16
  module.exports = class HanaTemplate extends TemplateBase {
14
17
  constructor(projectPath, generator) {
15
18
  super(projectPath, generator, __dirname);
16
- }
17
-
18
- async checkEnabled() {
19
- if (this.options.force) {
20
- return true;
21
- }
22
-
23
- const env = await this.getEnv();
24
-
25
- await Promise.all(['src/.hdiconfig', 'undeploy.json'].map(async(filePath) => {
26
- if (await this.fsUtil.pathExists(path.join(this.projectPath, env.folders.db, filePath))) {
27
- throw new Error(`File ${path.join(env.folders.db, filePath)} already exists. Use --force to overwrite.`);
28
- }
29
- }))
30
-
31
- return true;
19
+ this.projectReader = new ProjectReader(this);
32
20
  }
33
21
 
34
22
  // read env from project
@@ -42,28 +30,69 @@ module.exports = class HanaTemplate extends TemplateBase {
42
30
  }
43
31
  }
44
32
 
33
+ async runMTAMerging() {
34
+ const projectDescriptor = await this.projectReader.read(this.options);
35
+
36
+ const mtaYAMLPath = path.join(this.projectPath, 'mta.yaml');
37
+ if (!fse.existsSync(mtaYAMLPath)) {
38
+ console.warn(`There is no MTA file in your project. Run \`cds add mta\` to add an MTA file or create the HANA services yourself.`)
39
+ return;
40
+ }
41
+ const srv = projectDescriptor.cap.isNodejs ? srvNode : srvJava
42
+ const deployer = projectDescriptor.cap.isMultitenant ? null : hdbDeployer
43
+ const db = projectDescriptor.cap.isMultitenant ? serviceManager : hdiContainer
44
+ await this.templateUtil.mergeYAML(
45
+ mtaYAMLPath,
46
+ `${__dirname}/files/mta.yaml.hbs`,
47
+ projectDescriptor,
48
+ {
49
+ existences: [srv, deployer, db],
50
+ relationships: [{
51
+ in: srv.ref,
52
+ inKeyPath: ["requires"],
53
+ into: "name",
54
+ existences: [db.ref],
55
+ existenceKeyPath: ["name"],
56
+ },
57
+ !projectDescriptor.cap.isMultitenant && projectDescriptor.cap.isNodejs ?
58
+ {
59
+ in: deployer.ref,
60
+ inKeyPath: ["requires"],
61
+ into: "name",
62
+ existences: [db.ref],
63
+ existenceKeyPath: ["name"],
64
+ } : null],
65
+ }
66
+ );
67
+ }
68
+
45
69
  async run() {
46
70
  const env = await this.getEnv();
47
71
 
48
- await this.templateUtil.copyFiles('common', path.join(this.projectPath, env.folders.db), {
49
- projectName: this.projectName
50
- }, this.options.force);
72
+ const hdiConfigPath = path.join(this.projectPath, env.folders.db, 'src', '.hdiconfig');
73
+ const hdiConfigTemplatePath = path.join(__dirname, 'files', 'common', 'src', '.hdiconfig');
74
+ await this.templateUtil.mergeJSON(hdiConfigPath, hdiConfigTemplatePath);
75
+
76
+ const undeployJSONPath = path.join(this.projectPath, env.folders.db, 'undeploy.json');
77
+ const undeployJSONTemplatePath = path.join(__dirname, 'files', 'common', 'undeploy.json');
78
+ await this.templateUtil.mergeJSON(undeployJSONPath, undeployJSONTemplatePath);
51
79
 
52
- const cdsrcJsonPath = path.join(this.projectPath, '.cdsrc.json');
53
80
  const projectType = await this.getProjectType();
54
81
  switch (projectType) {
55
- case PROJECT_TYPE.java:
82
+ case PROJECT_TYPE.java: {
56
83
  await this.templateUtil.copyFiles('java', path.join(this.projectPath, env.folders.db), {}, this.options.force);
57
84
  await this._updatePomXml();
85
+ const cdsrcJsonPath = path.join(this.projectPath, '.cdsrc.json');
58
86
  await this._updateCdsrcJson(cdsrcJsonPath, env.folders.db, env);
59
87
  break;
60
-
88
+ }
61
89
  case PROJECT_TYPE.nodejs:
62
90
  await this._updatePackageJson(path.join(this.projectPath, 'package.json'), env.folders.db, env);
63
91
  break;
64
92
 
65
93
  default: break;
66
94
  }
95
+ await this.runMTAMerging()
67
96
  }
68
97
 
69
98
  async _updatePomXml() {
@@ -158,6 +187,6 @@ module.exports = class HanaTemplate extends TemplateBase {
158
187
  }
159
188
 
160
189
  _isUsingHana(db, env) {
161
- return env.get(`requires.${db}.kind`) === KIND_HANA || env.get(`requires.${db}.dialect`) === KIND_HANA || env.get(`requires.${db}.use`) === KIND_HANA;
190
+ return [`kind`, `dialect`, `use`].map(p => env.get(`requires.${db}.${p}`)).includes(KIND_HANA)
162
191
  }
163
192
  }
@@ -9,7 +9,7 @@ const mvnArchetypeUtil = require('../../util/mvnArchetypeUtil');
9
9
  const term = require('../../../util/term');
10
10
 
11
11
  const TemplateBase = require('../templateBase');
12
- const { COMMAND_ADD, URLS, OPTION_JAVA, OPTION_NODEJS, OPTION_MTX } = require('../../constants');
12
+ const { COMMAND_ADD, URLS, OPTION_JAVA, OPTION_NODEJS } = require('../../constants');
13
13
  const { nullLogger } = require('../../util/logger');
14
14
 
15
15
 
@@ -27,10 +27,6 @@ module.exports = class JavaTemplate extends TemplateBase {
27
27
  throw new Error(`Only one runtime per project is supported. Specify either ${OPTION_JAVA} or ${OPTION_NODEJS}.`);
28
28
  }
29
29
 
30
- if (this.options.add.has(OPTION_MTX)) {
31
- throw new Error(`The '${OPTION_MTX}' option can only be used for Node.js projects as of yet.`);
32
- }
33
-
34
30
  return true;
35
31
  }
36
32
 
@@ -1,239 +1,43 @@
1
- ## Generated mta.yaml based on template version 0.4.0
2
- ## appName = {{cap.appName}}
3
- ## language={{cap.pLanguage}}; multitenant={{cap.isMultitenant}}
4
- ## approuter={{ui.approuter}}
1
+ ---
5
2
  _schema-version: '3.1'
6
3
  ID: {{cap.appId}}
7
4
  version: {{cap.appVersion}}
8
5
  description: "{{cap.appDescription}}"
9
6
  parameters:
10
7
  enable-parallel-deployments: true
11
- {{#ui.approuter}}tenant-delimiter: "{{ui.tenantDelimiter}}" {{/ui.approuter}} {{~! ui.* context is an experimental feature }}
12
8
  build-parameters:
13
9
  before-all:
14
- - builder: custom
15
- commands:
10
+ - builder: custom
11
+ commands:
16
12
  {{#cap.isNodejs}}
17
- - npm ci
13
+ - npm ci
18
14
  {{/cap.isNodejs}}
19
15
  {{#cap.isJava}}
20
- - npm install --production
16
+ - npm install --production
21
17
  {{/cap.isJava}}
22
- - npx -p @sap/cds-dk cds build --production
18
+ - npx -p @sap/cds-dk cds build --production
23
19
 
24
- {{! This template creates one or two deployable modules:
25
- Java project, non-multitenant: Java server module + Node.js hdi deployer module
26
- Java project, multitenant: Java server module + Node.js cds-mtx module
27
- Node.js project, non-multitenant: Node.js server module + Node.js hdi deployer module
28
- Node.js project, multitenant: Node.js server module including cds-mtx }}
29
20
  modules:
30
- # --------------------- SERVER MODULE ------------------------
31
- - name: {{cap.appName}}-srv
32
- # ------------------------------------------------------------
33
- type: {{cap.pLanguage}}
34
- path: {{& cap.srv.path}}
21
+ - name: {{cap.appName}}-srv
22
+ type: {{cap.pLanguage}}
23
+ path: {{& cap.srv.path}}
35
24
  {{#cap.isNodejs}}
36
- parameters:
37
- buildpack: nodejs_buildpack
38
- build-parameters:
39
- builder: npm-ci
25
+ parameters:
26
+ buildpack: nodejs_buildpack
27
+ build-parameters:
28
+ builder: npm-ci
40
29
  {{/cap.isNodejs}}
41
30
  {{#cap.isJava}}
42
- parameters:
43
- buildpack: java_buildpack
31
+ parameters:
32
+ buildpack: java_buildpack
33
+ properties:
34
+ SPRING_PROFILES_ACTIVE: cloud
35
+ build-parameters:
36
+ builder: custom
37
+ commands: [ mvn clean package ]
38
+ build-result: "target/*-exec.[wj]ar"
44
39
  {{/cap.isJava}}
45
- {{#cap.isJava}}
46
- {{#cap.isMultitenant}}
47
- properties:
48
- SPRING_PROFILES_ACTIVE: cloud
49
- {{/cap.isMultitenant}}
50
- {{^cap.isMultitenant}}
51
- properties:
52
- SPRING_PROFILES_ACTIVE: cloud
53
- {{/cap.isMultitenant}}
54
- build-parameters:
55
- builder: custom
56
- commands: [ mvn clean package ]
57
- build-result: "target/*-exec.[wj]ar"
58
- {{/cap.isJava}}
59
- {{#cap.hasRequires}}
60
- requires:
61
- {{#cap.isJava}}
62
- {{#cap.isMultitenant}}
63
- - name: mtx-api # mtx sidecar binding
64
- properties:
65
- CDS_MTX_SDC_URL: ~{mtx-url}
66
- {{/cap.isMultitenant}}
67
- {{/cap.isJava}}
68
- # Resources extracted from CAP configuration
69
- {{#cap.requires}}
70
- - name: {{resource.name}}
71
- {{#cap.isJava}}
72
- {{/cap.isJava}}
73
- {{/cap.requires}}
74
- {{#cap.isMultitenant}}
75
- {{#cap.isNodejs}}
76
- - name: {{cap.appName}}-registry
77
- {{/cap.isNodejs}}
78
- {{/cap.isMultitenant}}
79
- {{/cap.hasRequires}}
80
- provides:
81
- - name: srv-api # required by consumers of CAP services (e.g. approuter)
82
- properties:
83
- srv-url: ${default-url}
84
- {{#cap.isNodejs}}
85
- {{#cap.isMultitenant}}
86
- - name: mtx-api # potentially required by approuter
87
- properties:
88
- mtx-url: ${default-url}
89
- {{/cap.isMultitenant}}
90
- {{/cap.isNodejs}}
91
-
92
- {{#cap.needsSidecar}}
93
- # -------------------- SIDECAR MODULE ------------------------
94
- - name: {{cap.appName}}-{{cap.db.0.name}}-deployer
95
- # ------------------------------------------------------------
96
- {{#cap.isMultitenant}}
97
- type: nodejs
98
- {{/cap.isMultitenant}}
99
- {{^cap.isMultitenant}}
100
- type: hdb
101
- {{/cap.isMultitenant}}
102
- path: {{& cap.db.0.path}} {{! Only consider one module for now }}
103
- parameters:
104
- buildpack: nodejs_buildpack
105
- {{#cap.hasRequires}}
106
- requires:
107
- # 'hana' and 'xsuaa' resources extracted from CAP configuration
108
- {{#cap.requires}}
109
- {{#resource.isHana}}
110
- - name: {{resource.name}}
111
- {{/resource.isHana}}
112
- {{#resource.isXsuaa}}
113
- - name: {{resource.name}}
114
- {{/resource.isXsuaa}}
115
- {{/cap.requires}}
116
- {{/cap.hasRequires}}
117
- {{#cap.isJava}}
118
- {{#cap.isMultitenant}}
119
- provides:
120
- - name: mtx-api # required by java server and potentially approuter
121
- properties:
122
- mtx-url: ${default-url}
123
- {{/cap.isMultitenant}}
124
- {{/cap.isJava}}
125
- {{/cap.needsSidecar}}
126
-
127
- {{#ui.approuter}}
128
- # ---------------------- APPROUTER ---------------------------
129
- - name: {{cap.appName}}
130
- # ------------------------------------------------------------
131
- type: approuter.nodejs
132
- path: {{& ui.appPath}} # from cds.env.folders. Consider also cds.env.build.target --> gen/app
133
- parameters:
134
- disk-quota: 256M # default in Web IDE
135
- memory: 256M # default in Web IDE
136
- hosts: # additional tenant specific hostnames (only for Canary)
137
- ## the developer will do this via an extension descriptor:
138
- # - <paas-subdomain >${tenant-delimiter}${host}
139
- # - <saas-subdomain1>${tenant-delimiter}${host}
140
- # - ...
141
- properties:
142
- TENANT_HOST_PATTERN: ^(.*)${tenant-delimiter}${default-uri} # only relevant for multiTenant
143
- requires:
144
- - name: uaa # binding to uaa
145
- - name: srv-api # binding to srv module
146
- group: destinations
147
- properties:
148
- name: srv-api # this is a name which must be used in xs-app.json as well !!!
149
- url: ~{srv-url}
150
- forwardAuthToken: true
151
- - name: mtx-api # in here always, but really used only if mtx client is used (our recommendation is that they contact cds-mtx via the approuter)
152
- group: destinations
153
- properties:
154
- name: mtx-api # this is a name which must be used in xs-app.json as well !!!
155
- url: ~{mtx-url}
156
- {{/ui.approuter}}
157
-
158
- {{#cap.hasRequires}}
159
- resources:
160
- # services extracted from CAP configuration
161
- # 'service-plan' can be configured via 'cds.requires.<name>.vcap.plan'
162
- {{#cap.requires}}
163
- # ------------------------------------------------------------
164
- - name: {{resource.name}}
165
- # ------------------------------------------------------------
166
- {{#resource.isHana}}
167
- {{#resource.isPlainHana}}
168
- type: com.sap.xs.hdi-container
169
- parameters:
170
- service: {{resource.service}} # or 'hanatrial' on trial landscapes
171
- {{/resource.isPlainHana}}
172
- {{#resource.isManagedHana}} {{! enable automatic switching to 'hanatrial' on trial accounts}}
173
- type: org.cloudfoundry.managed-service
174
- parameters:
175
- service: {{resource.service}}
176
- {{/resource.isManagedHana}}
177
- service-plan: {{resource.vcap.plan}}
178
- {{#resource.vcap.name}}
179
- service-name: {{resource.vcap.name}}
180
- {{/resource.vcap.name}}
181
- properties:
182
- hdi-service-name: ${service-name}
183
- {{/resource.isHana}}
184
- {{^resource.isHana}}
185
- type: org.cloudfoundry.managed-service
186
- parameters:
187
- {{#resource.isXsuaa}}
188
- service: xsuaa
189
- service-plan: application {{! This logic might be added to transformation coding. There are cases with two xsuaa}}
190
- {{#cap.isMultitenant}}
191
- path: ./xs-security.json
192
- {{/cap.isMultitenant}}
193
- {{#resource.vcap.name}}
194
- service-name: {{resource.vcap.name}}
195
- {{/resource.vcap.name}}
196
- config:
197
- xsappname: {{cap.appName}}-${space} # name + space dependency
198
- tenant-mode: {{#cap.isMultitenant}}shared{{/cap.isMultitenant}}{{^cap.isMultitenant}}dedicated{{/cap.isMultitenant}}
199
- {{/resource.isXsuaa}}
200
- {{^resource.isXsuaa}}
201
- service: {{resource.service}}
202
- service-plan: {{resource.vcap.plan}}
203
- {{#resource.vcap.name}}
204
- service-name: {{resource.vcap.name}}
205
- {{/resource.vcap.name}}
206
- {{/resource.isXsuaa}}
207
- {{/resource.isHana}}
208
- {{/cap.requires}}
209
- {{/cap.hasRequires}}
210
-
211
- {{#cap.isMultitenant}}
212
- {{#cap.isNodejs}}
213
- - name: {{cap.appName}}-registry
214
- type: org.cloudfoundry.managed-service
215
- requires:
216
- - name: {{cap.appName}}-uaa-mt
217
- - name: mtx-api
40
+ provides:
41
+ - name: srv-api # required by consumers of CAP services (e.g. approuter)
218
42
  properties:
219
- prop: ~{mtx-url}
220
- parameters:
221
- param: ~{mtx-url}
222
- parameters:
223
- service: saas-registry
224
- service-plan: application
225
- config:
226
- xsappname: {{cap.appName}}-${space}
227
- appName: {{cap.appName}}
228
- displayName: {{cap.appName}}
229
- description: {{cap.appDescription}}
230
- #category: 'Category'
231
- appUrls:
232
- onSubscription: ~{mtx-api/mtx-url}/mtx/v1/provisioning/tenant/{tenantId}
233
- onSubscriptionAsync: false
234
- onUnSubscriptionAsync: false
235
- callbackTimeoutMillis: 300000
236
- {{/cap.isNodejs}}
237
- {{/cap.isMultitenant}}
238
-
239
- {{! consider vcap.tag as well}}
43
+ srv-url: ${default-url}
@@ -1,28 +1,36 @@
1
- const path = require('path')
1
+ const path = require('path');
2
2
  const TemplateBase = require('../templateBase');
3
- const ProjectReader = require('../mta/projectReader')
4
-
3
+ const ProjectReader = require('../../util/projectReader');
5
4
 
6
5
  module.exports = class MtaTemplate extends TemplateBase {
7
6
  constructor(projectPath, generator) {
8
7
  super(projectPath, generator, __dirname);
9
- this.projectReader = new ProjectReader(this)
8
+ this.projectReader = new ProjectReader(this);
10
9
  }
11
10
 
12
- async checkEnabled() {
13
- if (this.options.force) {
14
- return true;
11
+ async run() {
12
+ const projectDescriptor = await this.projectReader.read();
13
+ if (!await this.fsUtil.pathExists(path.join(this.projectPath, 'mta.yaml'))) {
14
+ await this.templateUtil.copyFiles('.', this.projectPath, projectDescriptor);
15
15
  }
16
16
 
17
- if (await this.fsUtil.pathExists(path.join(this.projectPath, 'mta.yaml'))) {
18
- throw new Error(`File mta.yaml already exists in current folder. Use --force to overwrite.`);
17
+ // Re-applying the merging part of `cds add xsuaa`, `cds add hana`, and `cds add mtx`, if necessary.
18
+ // TODO: Find a generic solution for situation like these. Probably involves some restructuring in the
19
+ // project reader, so that there's a logical mapping from hasX to XTemplate.
20
+ if (projectDescriptor.cap.hasHana) {
21
+ const HanaTemplate = require(`../hana`)
22
+ const template = new HanaTemplate(this.projectPath, this.generator)
23
+ await template.runMTAMerging()
24
+ }
25
+ if (projectDescriptor.cap.hasXsuaa) {
26
+ const XsuaaTemplate = require(`../xsuaa`)
27
+ const template = new XsuaaTemplate(this.projectPath, this.generator)
28
+ await template.runMTAMerging()
29
+ }
30
+ if (projectDescriptor.cap.isMultitenant) {
31
+ const MtxTemplate = require(`../mtx`)
32
+ const template = new MtxTemplate(this.projectPath, this.generator)
33
+ await template.runMTAMerging()
19
34
  }
20
-
21
- return true;
22
- }
23
-
24
- async run() {
25
- const projectDescriptor = await this.projectReader.read()
26
- await this.templateUtil.copyFiles('.', this.projectPath, projectDescriptor, this.options.force);
27
35
  }
28
- }
36
+ };
@@ -0,0 +1,24 @@
1
+ {
2
+ "cds": {
3
+ "requires": {
4
+ "auth": {
5
+ "strategy": "JWT"
6
+ },
7
+ "db": {
8
+ "kind": { "#overwrite": "hana" },
9
+ "vcap": {
10
+ "label": "service-manager"
11
+ }
12
+ },
13
+ "multitenancy": true
14
+ },
15
+ "hana": {
16
+ "deploy-format": "hdbtable"
17
+ },
18
+ "mtx": {
19
+ "element-prefix": "Z_",
20
+ "namespace-blocklist": [],
21
+ "extension-allowlist": []
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "dependencies": {
3
+ "@sap/cds-mtx": "^2"
4
+ }
5
+ }
@@ -0,0 +1,74 @@
1
+ ---
2
+ modules:
3
+ - name: {{cap.appName}}-srv
4
+ type: {{cap.pLanguage}}
5
+ path: {{& cap.srv.path}}
6
+ {{#cap.isNodejs}}
7
+ properties:
8
+ SUBSCRIPTION_URL: ${protocol}://\${tenant_subdomain}-${default-uri}
9
+ SUBSCRIPTION_URL_REPLACEMENT_RULES: [['-srv', '']]
10
+ {{/cap.isNodejs}}
11
+ requires:
12
+ - name: {{cap.appName}}-registry
13
+ {{#cap.isJava}}
14
+ - name: sidecar
15
+ properties:
16
+ CDS_MULTITENANCY_SIDECAR_URL: ~{url}
17
+ {{/cap.isJava}}
18
+ provides:
19
+ - name: srv-api # required by consumers of CAP services (e.g. approuter)
20
+ properties:
21
+ srv-url: ${default-url}
22
+ {{#cap.isNodejs}}
23
+ - name: mtx-api # potentially required by approuter
24
+ properties:
25
+ mtx-url: ${default-url}
26
+ {{/cap.isNodejs}}
27
+
28
+ {{#cap.isJava}}
29
+ - name: {{cap.appName}}-mtx-sidecar
30
+ type: nodejs
31
+ path: mtx-sidecar
32
+ parameters:
33
+ memory: 256M
34
+ disk-quota: 512M
35
+ requires:
36
+ - name: bookshop-db
37
+ - name: bookshop-uaa
38
+ provides:
39
+ - name: sidecar
40
+ properties:
41
+ url: ${default-url}
42
+ {{/cap.isJava}}
43
+
44
+ resources:
45
+ - name: {{cap.appName}}-registry
46
+ type: org.cloudfoundry.managed-service
47
+ requires:
48
+ {{#cap.isNodejs}}
49
+ - name: mtx-api
50
+ {{/cap.isNodejs}}
51
+ {{#cap.isJava}}
52
+ - name: srv-api
53
+ {{/cap.isJava}}
54
+ parameters:
55
+ service: saas-registry
56
+ service-plan: application
57
+ config:
58
+ xsappname: {{cap.appName}}-${org}-${space}
59
+ appName: {{cap.appName}}-${org}-${space}
60
+ displayName: {{cap.appName}}
61
+ description: A simple CAP project.
62
+ category: 'Category'
63
+ appUrls:
64
+ {{#cap.isNodejs}}
65
+ getDependencies: ~{mtx-api/mtx-url}/mtx/v1/provisioning/dependencies
66
+ onSubscription: ~{mtx-api/mtx-url}/mtx/v1/provisioning/tenant/{tenantId}
67
+ {{/cap.isNodejs}}
68
+ {{#cap.isJava}}
69
+ getDependencies: ~${srv-api/srv-url}/mt/v1.0/subscriptions/dependencies
70
+ onSubscription: ~${srv-api/srv-url}/mt/v1.0/subscriptions/tenants/{tenantId}
71
+ {{/cap.isJava}}
72
+ onSubscriptionAsync: false
73
+ onUnSubscriptionAsync: false
74
+ callbackTimeoutMillis: 300000
@@ -1,14 +1,28 @@
1
1
  {
2
- "xsappname": "{{cap.appName}}-${space}",
3
- "tenant-mode": "shared",
4
2
  "scopes": [
5
- { "name": "$XSAPPNAME.ExtendCDS", "description": "Extend CDS application" },
6
- { "name": "$XSAPPNAME.ExtendCDSdelete", "description": "Extend CDS application with undeploy" },
7
- { "name": "$XSAPPNAME.MtxDiagnose", "description": "Diagnose MTX sidecar" },
8
- { "name": "$XSAPPNAME.mtdeployment", "description": "Deploy applications" },
9
- { "name": "$XSAPPNAME.mtcallback", "description": "Subscribe to applications", "grant-as-authority-to-apps": [
10
- "$XSAPPNAME(application,sap-provisioning,tenant-onboarding)"
11
- ]}
3
+ {
4
+ "name": "$XSAPPNAME.ExtendCDS",
5
+ "description": "Extend CDS applications"
6
+ },
7
+ {
8
+ "name": "$XSAPPNAME.ExtendCDSdelete",
9
+ "description": "Extend CDS applications with undeployments"
10
+ },
11
+ {
12
+ "name": "$XSAPPNAME.MtxDiagnose",
13
+ "description": "Diagnose MTX"
14
+ },
15
+ {
16
+ "name": "$XSAPPNAME.mtdeployment",
17
+ "description": "Deploy applications"
18
+ },
19
+ {
20
+ "name": "$XSAPPNAME.mtcallback",
21
+ "description": "Subscribe to applications",
22
+ "grant-as-authority-to-apps": [
23
+ "$XSAPPNAME(application,sap-provisioning,tenant-onboarding)"
24
+ ]
25
+ }
12
26
  ],
13
27
  "authorities": [
14
28
  "$XSAPPNAME.MtxDiagnose",