@sap/cds-dk 4.6.4 → 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 (74) hide show
  1. package/CHANGELOG.md +68 -1
  2. package/bin/activate.js +5 -1
  3. package/bin/add.js +2 -1
  4. package/bin/bind.js +121 -48
  5. package/bin/cds.js +8 -0
  6. package/bin/env.js +0 -2
  7. package/bin/repl.js +5 -2
  8. package/bin/watch.js +10 -7
  9. package/lib/bind/bindingResolver.js +26 -14
  10. package/lib/bind/bindingUtil.js +144 -0
  11. package/lib/bind/cfKeyProvider.js +2 -80
  12. package/lib/bind/kubernetesCredentialsProvider.js +157 -0
  13. package/lib/bind/userCdsrcJsonStorageProvider.js +7 -7
  14. package/lib/client/activate.js +16 -13
  15. package/lib/client/base_command.js +5 -1
  16. package/lib/client/helper/cf_helper.js +5 -2
  17. package/lib/client/params.js +16 -2
  18. package/lib/client/settings_manager.js +15 -8
  19. package/lib/compile/openapi/csdl2openapi.js +6 -8
  20. package/lib/compile/to-xsuaa.js +0 -14
  21. package/lib/import/utils/MetadataConverter.js +6 -4
  22. package/lib/import/utils/MultiMap.js +1 -0
  23. package/lib/import/v2parser.js +150 -64
  24. package/lib/import/v4parser.js +118 -56
  25. package/lib/index.js +6 -5
  26. package/lib/init/constants.js +11 -5
  27. package/lib/init/index.js +14 -7
  28. package/lib/init/template/_merging/existences.js +161 -0
  29. package/lib/init/template/approuter/files/default-env.json +9 -0
  30. package/lib/init/template/approuter/files/mta.yaml.hbs +48 -0
  31. package/lib/init/template/approuter/files/package.json +9 -0
  32. package/lib/init/template/approuter/files/xs-app.json +8 -0
  33. package/lib/init/template/approuter/index.js +66 -0
  34. package/lib/init/template/auditlog/files/dependencies.package.json +5 -0
  35. package/lib/init/template/auditlog/files/mta.yaml.hbs +13 -0
  36. package/lib/init/template/auditlog/index.js +38 -0
  37. package/lib/init/template/cf-manifest/index.js +1 -1
  38. package/lib/init/template/data/index.js +18 -6
  39. package/lib/init/template/hana/files/common/undeploy.json +5 -0
  40. package/lib/init/template/hana/files/java/package.json +3 -0
  41. package/lib/init/template/hana/files/mta.yaml.hbs +42 -0
  42. package/lib/init/template/hana/files/nodejs/dependencies.package.json +5 -0
  43. package/lib/init/template/hana/index.js +53 -24
  44. package/lib/init/template/java/index.js +1 -5
  45. package/lib/init/template/lint/index.js +17 -1
  46. package/lib/init/template/mta/files/mta.yaml.hbs +27 -216
  47. package/lib/init/template/mta/index.js +25 -17
  48. package/lib/init/template/mtx/files/cds.package.json +24 -0
  49. package/lib/init/template/mtx/files/dependencies.package.json +5 -0
  50. package/lib/init/template/mtx/files/mta.yaml.hbs +74 -0
  51. package/lib/init/template/mtx/files/xs-security.json.hbs +23 -9
  52. package/lib/init/template/mtx/index.js +126 -29
  53. package/lib/init/template/templateBase.js +14 -0
  54. package/lib/init/template/xsuaa/files/cds.package.json +9 -0
  55. package/lib/init/template/xsuaa/files/dependencies.package.json +6 -0
  56. package/lib/init/template/xsuaa/files/mta.yaml.hbs +17 -0
  57. package/lib/init/template/xsuaa/index.js +75 -0
  58. package/lib/init/util/fsUtil.js +18 -4
  59. package/lib/init/util/logger.js +3 -1
  60. package/lib/init/util/mvnArchetypeUtil.js +3 -1
  61. package/lib/init/{template/mta → util}/projectReader.js +26 -11
  62. package/lib/init/util/templateUtil.js +267 -3
  63. package/lib/lint/Linter.js +1 -2
  64. package/lib/lint/io.js +3 -12
  65. package/lib/util/exec.d.ts +54 -0
  66. package/lib/util/exec.js +210 -0
  67. package/lib/watch/livereload-server.js +43 -31
  68. package/lib/watch/node-watch.js +46 -20
  69. package/lib/watch/open.js +1 -1
  70. package/npm-shrinkwrap.json +3382 -9106
  71. package/package.json +8 -9
  72. package/readme.md +1 -1
  73. package/lib/init/template/mtx/package/cds.package.json +0 -29
  74. package/lib/init/template/mtx/package/dependencies.package.json +0 -9
@@ -1,232 +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:
16
- - npm install --production
17
- - npx -p @sap/cds-dk cds build --production
18
-
19
- {{! This template creates one or two deployable modules:
20
- Java project, non-multitenant: Java server module + Node.js hdi deployer module
21
- Java project, multitenant: Java server module + Node.js cds-mtx module
22
- Node.js project, non-multitenant: Node.js server module + Node.js hdi deployer module
23
- Node.js project, multitenant: Node.js server module including cds-mtx }}
24
- modules:
25
- # --------------------- SERVER MODULE ------------------------
26
- - name: {{cap.appName}}-srv
27
- # ------------------------------------------------------------
28
- type: {{cap.pLanguage}}
29
- path: {{& cap.srv.path}}
10
+ - builder: custom
11
+ commands:
30
12
  {{#cap.isNodejs}}
31
- parameters:
32
- buildpack: nodejs_buildpack
13
+ - npm ci
33
14
  {{/cap.isNodejs}}
34
15
  {{#cap.isJava}}
35
- parameters:
36
- buildpack: java_buildpack
37
- {{/cap.isJava}}
38
- {{#cap.isJava}}
39
- {{#cap.isMultitenant}}
40
- properties:
41
- SPRING_PROFILES_ACTIVE: cloud
42
- {{/cap.isMultitenant}}
43
- {{^cap.isMultitenant}}
44
- properties:
45
- SPRING_PROFILES_ACTIVE: cloud
46
- {{/cap.isMultitenant}}
47
- build-parameters:
48
- builder: custom
49
- commands: [ mvn clean package ]
50
- build-result: "target/*-exec.[wj]ar"
51
- {{/cap.isJava}}
52
- {{#cap.hasRequires}}
53
- requires:
54
- {{#cap.isJava}}
55
- {{#cap.isMultitenant}}
56
- - name: mtx-api # mtx sidecar binding
57
- properties:
58
- CDS_MTX_SDC_URL: ~{mtx-url}
59
- {{/cap.isMultitenant}}
60
- {{/cap.isJava}}
61
- # Resources extracted from CAP configuration
62
- {{#cap.requires}}
63
- - name: {{resource.name}}
64
- {{#cap.isJava}}
16
+ - npm install --production
65
17
  {{/cap.isJava}}
66
- {{/cap.requires}}
67
- {{#cap.isMultitenant}}
68
- {{#cap.isNodejs}}
69
- - name: {{cap.appName}}-registry
70
- {{/cap.isNodejs}}
71
- {{/cap.isMultitenant}}
72
- {{/cap.hasRequires}}
73
- provides:
74
- - name: srv-api # required by consumers of CAP services (e.g. approuter)
75
- properties:
76
- srv-url: ${default-url}
18
+ - npx -p @sap/cds-dk cds build --production
19
+
20
+ modules:
21
+ - name: {{cap.appName}}-srv
22
+ type: {{cap.pLanguage}}
23
+ path: {{& cap.srv.path}}
77
24
  {{#cap.isNodejs}}
78
- {{#cap.isMultitenant}}
79
- - name: mtx-api # potentially required by approuter
80
- properties:
81
- mtx-url: ${default-url}
82
- {{/cap.isMultitenant}}
25
+ parameters:
26
+ buildpack: nodejs_buildpack
27
+ build-parameters:
28
+ builder: npm-ci
83
29
  {{/cap.isNodejs}}
84
-
85
- {{#cap.needsSidecar}}
86
- # -------------------- SIDECAR MODULE ------------------------
87
- - name: {{cap.appName}}-{{cap.db.0.name}}-deployer
88
- # ------------------------------------------------------------
89
- {{#cap.isMultitenant}}
90
- type: nodejs
91
- {{/cap.isMultitenant}}
92
- {{^cap.isMultitenant}}
93
- type: hdb
94
- {{/cap.isMultitenant}}
95
- path: {{& cap.db.0.path}} {{! Only consider one module for now }}
96
- parameters:
97
- buildpack: nodejs_buildpack
98
- {{#cap.hasRequires}}
99
- requires:
100
- # 'hana' and 'xsuaa' resources extracted from CAP configuration
101
- {{#cap.requires}}
102
- {{#resource.isHana}}
103
- - name: {{resource.name}}
104
- {{/resource.isHana}}
105
- {{#resource.isXsuaa}}
106
- - name: {{resource.name}}
107
- {{/resource.isXsuaa}}
108
- {{/cap.requires}}
109
- {{/cap.hasRequires}}
110
30
  {{#cap.isJava}}
111
- {{#cap.isMultitenant}}
112
- provides:
113
- - name: mtx-api # required by java server and potentially approuter
114
- properties:
115
- mtx-url: ${default-url}
116
- {{/cap.isMultitenant}}
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"
117
39
  {{/cap.isJava}}
118
- {{/cap.needsSidecar}}
119
-
120
- {{#ui.approuter}}
121
- # ---------------------- APPROUTER ---------------------------
122
- - name: {{cap.appName}}
123
- # ------------------------------------------------------------
124
- type: approuter.nodejs
125
- path: {{& ui.appPath}} # from cds.env.folders. Consider also cds.env.build.target --> gen/app
126
- parameters:
127
- disk-quota: 256M # default in Web IDE
128
- memory: 256M # default in Web IDE
129
- hosts: # additional tenant specific hostnames (only for Canary)
130
- ## the developer will do this via an extension descriptor:
131
- # - <paas-subdomain >${tenant-delimiter}${host}
132
- # - <saas-subdomain1>${tenant-delimiter}${host}
133
- # - ...
134
- properties:
135
- TENANT_HOST_PATTERN: ^(.*)${tenant-delimiter}${default-uri} # only relevant for multiTenant
136
- requires:
137
- - name: uaa # binding to uaa
138
- - name: srv-api # binding to srv module
139
- group: destinations
140
- properties:
141
- name: srv-api # this is a name which must be used in xs-app.json as well !!!
142
- url: ~{srv-url}
143
- forwardAuthToken: true
144
- - 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)
145
- group: destinations
146
- properties:
147
- name: mtx-api # this is a name which must be used in xs-app.json as well !!!
148
- url: ~{mtx-url}
149
- {{/ui.approuter}}
150
-
151
- {{#cap.hasRequires}}
152
- resources:
153
- # services extracted from CAP configuration
154
- # 'service-plan' can be configured via 'cds.requires.<name>.vcap.plan'
155
- {{#cap.requires}}
156
- # ------------------------------------------------------------
157
- - name: {{resource.name}}
158
- # ------------------------------------------------------------
159
- {{#resource.isHana}}
160
- {{#resource.isPlainHana}}
161
- type: com.sap.xs.hdi-container
162
- parameters:
163
- service: {{resource.service}} # or 'hanatrial' on trial landscapes
164
- {{/resource.isPlainHana}}
165
- {{#resource.isManagedHana}} {{! enable automatic switching to 'hanatrial' on trial accounts}}
166
- type: org.cloudfoundry.managed-service
167
- parameters:
168
- service: {{resource.service}}
169
- {{/resource.isManagedHana}}
170
- service-plan: {{resource.vcap.plan}}
171
- {{#resource.vcap.name}}
172
- service-name: {{resource.vcap.name}}
173
- {{/resource.vcap.name}}
174
- properties:
175
- hdi-service-name: ${service-name}
176
- {{/resource.isHana}}
177
- {{^resource.isHana}}
178
- type: org.cloudfoundry.managed-service
179
- parameters:
180
- {{#resource.isXsuaa}}
181
- service: xsuaa
182
- service-plan: application {{! This logic might be added to transformation coding. There are cases with two xsuaa}}
183
- {{#cap.isMultitenant}}
184
- path: ./xs-security.json
185
- {{/cap.isMultitenant}}
186
- {{#resource.vcap.name}}
187
- service-name: {{resource.vcap.name}}
188
- {{/resource.vcap.name}}
189
- config:
190
- xsappname: {{cap.appName}}-${space} # name + space dependency
191
- tenant-mode: {{#cap.isMultitenant}}shared{{/cap.isMultitenant}}{{^cap.isMultitenant}}dedicated{{/cap.isMultitenant}}
192
- {{/resource.isXsuaa}}
193
- {{^resource.isXsuaa}}
194
- service: {{resource.service}}
195
- service-plan: {{resource.vcap.plan}}
196
- {{#resource.vcap.name}}
197
- service-name: {{resource.vcap.name}}
198
- {{/resource.vcap.name}}
199
- {{/resource.isXsuaa}}
200
- {{/resource.isHana}}
201
- {{/cap.requires}}
202
- {{/cap.hasRequires}}
203
-
204
- {{#cap.isMultitenant}}
205
- {{#cap.isNodejs}}
206
- - name: {{cap.appName}}-registry
207
- type: org.cloudfoundry.managed-service
208
- requires:
209
- - name: {{cap.appName}}-uaa-mt
210
- - name: mtx-api
211
- properties:
212
- prop: ~{mtx-url}
213
- parameters:
214
- param: ~{mtx-url}
215
- parameters:
216
- service: saas-registry
217
- service-plan: application
218
- config:
219
- xsappname: {{cap.appName}}-${space}
220
- appName: {{cap.appName}}
221
- displayName: {{cap.appName}}
222
- description: {{cap.appDescription}}
223
- #category: 'Category'
224
- appUrls:
225
- onSubscription: ~{mtx-api/mtx-url}/mtx/v1/provisioning/tenant/{tenantId}
226
- onSubscriptionAsync: false
227
- onUnSubscriptionAsync: false
228
- callbackTimeoutMillis: 300000
229
- {{/cap.isNodejs}}
230
- {{/cap.isMultitenant}}
231
-
232
- {{! consider vcap.tag as well}}
40
+ provides:
41
+ - name: srv-api # required by consumers of CAP services (e.g. approuter)
42
+ properties:
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",
@@ -1,45 +1,142 @@
1
- const TemplateBase = require('../templateBase');
2
- const ProjectReader = require('../mta/projectReader');
3
- const { COMMAND_ADD, OPTION_HANA } = require('../../constants');
4
-
1
+ const TemplateBase = require('../templateBase')
2
+ const ProjectReader = require('../../util/projectReader')
3
+ const { fse } = require('@sap/cds-foss')
4
+ const path = require('path')
5
+ const { OPTION_HANA, OPTION_XSUAA } = require('../../constants')
6
+ const { srvNode, srvJava, saasRegistry, mtxSidecar, mtxAPI, srvAPI, hdiContainer, xsuaa } = require('../_merging/existences');
5
7
 
6
8
  module.exports = class MtxTemplate extends TemplateBase {
7
9
  constructor(projectPath, generator) {
8
- super(projectPath, generator, __dirname);
9
- this.projectReader = new ProjectReader(this);
10
+ super(projectPath, generator, __dirname)
11
+ this.projectReader = new ProjectReader(this)
10
12
  }
11
13
 
12
14
  async getDependencies() {
13
- return [OPTION_HANA];
15
+ return [OPTION_HANA, OPTION_XSUAA]
14
16
  }
15
17
 
16
- async checkEnabled() {
17
- if (this.options._cmd === COMMAND_ADD) {
18
- throw new Error(`You can't add multitenancy to an existing project.`);
18
+ async runMTAMerging() {
19
+ const projectDescriptor = await this.projectReader.read()
20
+
21
+ const mtaYAMLPath = path.join(this.projectPath, 'mta.yaml');
22
+ if (!fse.existsSync(mtaYAMLPath)) {
23
+ console.warn(`There is no MTA file in your project. Run \`cds add mta\` to add an MTA file or create the MTX services yourself.`)
24
+ return;
19
25
  }
20
26
 
21
- return true;
22
- }
27
+ const mergingRules = projectDescriptor.cap.isNodejs ?
28
+ {
29
+ existences: [srvNode, saasRegistry, mtxAPI, xsuaa],
30
+ overwrites: [{
31
+ in: xsuaa.ref,
32
+ keyPath: ["parameters", "config", "tenant-mode"],
33
+ replacement: "shared"
34
+ }],
35
+ deletions: [hdiContainer],
36
+ relationships: [{
37
+ in: srvNode.ref,
38
+ inKeyPath: ["requires"],
39
+ into: "name",
40
+ existences: [saasRegistry.ref],
41
+ existenceKeyPath: ["name"],
42
+ }],
43
+ }
44
+ :
45
+ {
46
+ existences: [srvJava, srvAPI, mtxSidecar, saasRegistry],
47
+ relationships: [{
48
+ in: srvJava.ref,
49
+ inKeyPath: ["requires"],
50
+ into: "name",
51
+ existences: [saasRegistry.ref, mtxSidecar.ref],
52
+ existenceKeyPath: ["name"],
53
+ }],
54
+ }
23
55
 
24
- async run() {
25
- await this._writePackageJson();
26
- const projectDescriptor = await this.projectReader.read();
27
- await this.templateUtil.copyFiles('.', this.projectPath, projectDescriptor);
56
+ await this.templateUtil.mergeYAML(
57
+ mtaYAMLPath,
58
+ path.join(__dirname, `files`, `mta.yaml.hbs`),
59
+ projectDescriptor,
60
+ mergingRules
61
+ )
28
62
  }
29
63
 
30
- async _writePackageJson() {
31
- const packageJSONPath = `${this.projectPath}/package.json`;
32
- const packageJSON = await this.fsUtil.readJSON(packageJSONPath);
33
- const filePaths = await this.fsUtil.readdir(`${__dirname}/package/`);
34
- const templatePaths = filePaths.filter(path => path.endsWith(`.package.json`));
35
-
36
- for (const fileName of templatePaths) {
37
- const key = fileName.split(`.package.json`)[0];
38
- const templateJSON = await this.fsUtil.readJSON(`${__dirname}/package/${fileName}`);
39
- packageJSON[key] = packageJSON[key] || {};
40
- Object.assign(packageJSON[key], templateJSON);
41
- }
64
+ async runXSSecurityMerging() {
65
+ const projectDescriptor = await this.projectReader.read()
66
+ const mtxPath = projectDescriptor.cap.isJava ? 'mtx-sidecar' : ''
67
+ await this.templateUtil.mergeJSON(
68
+ path.join(this.projectPath, mtxPath, 'xs-security.json'),
69
+ path.join(__dirname, 'files', 'xs-security.json.hbs'),
70
+ projectDescriptor,
71
+ {
72
+ existences: [{
73
+ ref: "scope-diagnose",
74
+ keyPath: ["scopes"],
75
+ constraints: [{
76
+ comparisonKeyPath: ["name"],
77
+ value: "$XSAPPNAME.MtxDiagnose"
78
+ }],
79
+ }, {
80
+ ref: "scope-subscription",
81
+ keyPath: ["scopes"],
82
+ constraints: [{
83
+ comparisonKeyPath: ["name"],
84
+ value: "$XSAPPNAME.mtcallback"
85
+ }],
86
+ }, {
87
+ ref: "scope-update",
88
+ keyPath: ["scopes"],
89
+ constraints: [{
90
+ comparisonKeyPath: ["name"],
91
+ value: "$XSAPPNAME.mtdeployment"
92
+ }],
93
+ }, {
94
+ ref: "scope-extend",
95
+ keyPath: ["scopes"],
96
+ constraints: [{
97
+ comparisonKeyPath: ["name"],
98
+ value: "$XSAPPNAME.ExtendCDS"
99
+ }],
100
+ }, {
101
+ ref: "scope-extend-delete",
102
+ keyPath: ["scopes"],
103
+ constraints: [{
104
+ comparisonKeyPath: ["name"],
105
+ value: "$XSAPPNAME.ExtendCDSdelete"
106
+ }],
107
+ }, {
108
+ ref: "template-mt-administrator",
109
+ keyPath: ["role-templates"],
110
+ constraints: [{
111
+ comparisonKeyPath: ["name"],
112
+ value: "MultitenancyAdministrator"
113
+ }],
114
+ }, {
115
+ ref: "template-extension-developer",
116
+ keyPath: ["role-templates"],
117
+ constraints: [{
118
+ comparisonKeyPath: ["name"],
119
+ value: "ExtensionDeveloper"
120
+ }],
121
+ }, {
122
+ ref: "template-extension-developer-undeploy",
123
+ keyPath: ["role-templates"],
124
+ constraints: [{
125
+ comparisonKeyPath: ["name"],
126
+ value: "ExtensionDeveloperUndeploy"
127
+ }],
128
+ }],
129
+ }
130
+ )
131
+ }
42
132
 
43
- await this.fsUtil.writeJSON(packageJSONPath, JSON.parse(JSON.stringify(packageJSON)));
133
+ async run() {
134
+ const projectDescriptor = await this.projectReader.read()
135
+ const mtxPath = projectDescriptor.cap.isJava ? 'mtx-sidecar' : ''
136
+ const packageJsonPath = path.join(this.projectPath, mtxPath, 'package.json')
137
+ await this.templateUtil.mergeJSON(packageJsonPath, path.join(__dirname, 'files', 'cds.package.json'))
138
+ await this.templateUtil.mergeJSON(packageJsonPath, path.join(__dirname, 'files', 'dependencies.package.json'))
139
+ await this.runXSSecurityMerging()
140
+ await this.runMTAMerging()
44
141
  }
45
142
  }
@@ -57,6 +57,20 @@ module.exports = class TemplateBase {
57
57
  return Config.for('cds', projectPath);
58
58
  }
59
59
 
60
+ /**
61
+ * @abstract
62
+ * Executes the given template's merging steps.
63
+ * The separation from `run()` is necessary to preserve templating associativity,
64
+ * i.e. the order in which you apply them does not matter.
65
+ * Ex.: Assume `cds add hana` is called before `cds add mta`. We want `cds add mta`
66
+ * to create the base mta.yaml template and merge the hana mta.yaml in, but _don't_
67
+ * want any other steps from the hana template performed (e.g. creating the .hdiconfig).
68
+ * Separating the two let's us run this _only_ the merging part of the template.
69
+ */
70
+ async runMTAMerging() {
71
+
72
+ }
73
+
60
74
  /**
61
75
  * @abstract
62
76
  * Executes the given template.
@@ -0,0 +1,9 @@
1
+ {
2
+ "cds": {
3
+ "requires": {
4
+ "uaa": {
5
+ "kind": "xsuaa"
6
+ }
7
+ }
8
+ }
9
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "dependencies": {
3
+ "@sap/xssec": "^3",
4
+ "passport": "^0"
5
+ }
6
+ }