@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
@@ -121,12 +121,19 @@ function _validateJSON(jsonObj) {
121
121
  }
122
122
 
123
123
  function _includeExternalNamespaceAnnotation(source,target){
124
- Object.entries(source).forEach(element =>{
125
- if(element[0].startsWith('@')){
124
+ Object.entries(source).forEach(element => {
125
+ if (element[0].startsWith('@')) {
126
126
  target[element[0]] = element[1];
127
- }
127
+ }
128
128
  });
129
129
  }
130
+
131
+ function _propertyWithItems(property) {
132
+ let items = {};
133
+ items["items"] = property;
134
+ return items;
135
+ }
136
+
130
137
  function generatePropertyCsn(propertyType, isPrimaryKey) {
131
138
  let property = {};
132
139
  if (isPrimaryKey) {
@@ -167,23 +174,32 @@ function generatePropertyCsn(propertyType, isPrimaryKey) {
167
174
  property.type = 'cds.LargeString'; // if type is missing, then it is String type
168
175
  }
169
176
 
170
- if(edmxncdsdatatype[propertyType.$Type + '_a'])
171
- {
177
+ if (edmxncdsdatatype[propertyType.$Type + '_a']) {
172
178
  property["@odata.type"] = propertyType.$Type;
173
179
  }
174
180
 
181
+ if (propertyType.$Collection == true) {
182
+ return _propertyWithItems(property);
183
+ }
184
+
175
185
  return property;
176
186
  }
177
187
 
178
188
  function _generateComplexTypePropertyCsn(propertyType) {
179
189
  let property = {};
180
190
  property.type = propertyType.$Type;
191
+ if (propertyType.$Collection == true) {
192
+ return _propertyWithItems(property);
193
+ }
181
194
  return property;
182
195
  }
183
196
 
184
197
  function _generateTypeDefinitionPropertyCsn(propertyType) {
185
198
  let property = {};
186
199
  property.type = propertyType.$Type;
200
+ if (propertyType.$Collection == true) {
201
+ return _propertyWithItems(property);
202
+ }
187
203
  return property;
188
204
  }
189
205
 
@@ -371,10 +387,18 @@ function _parseEntityType(schemaDataList, ignorePersistenceSkip, mockServerUc) {
371
387
  schemaData = schemaDataList[i];
372
388
  _generateEntityType(entityTypes, schemaData, mockServerUc);
373
389
  }
374
- // parse it
375
390
  return _generateCSNForEntityType(entityTypes, ignorePersistenceSkip, mockServerUc);
376
391
  }
377
-
392
+ function _parseEntityContainer(entityCSN, schemaData){
393
+ Object.entries(schemaData[0]['EntityContainer']).forEach(entry => {
394
+ if(entityCSN[namespace + '.' + entry[0]])
395
+ _includeExternalNamespaceAnnotation(entry[1],entityCSN[namespace + '.' + entry[0]]);
396
+ if(entry[0].startsWith('@')){
397
+ entityCSN[namespace][entry[0]]= entry[1];
398
+ }
399
+ });
400
+ return entityCSN;
401
+ }
378
402
  function _generateEnumType(schemaData) {
379
403
  let enumTypeDict = {};
380
404
  let temp;
@@ -531,9 +555,9 @@ function _parseBounded(csnDefs, flag) {
531
555
  let type = _getDatatype(paramObj.$Type);
532
556
  if(type) paramType["type"] = type;
533
557
  }
534
- if (paramType.type) {
558
+ if (paramType.type || paramType.items.type) {
535
559
  // check if parameter type is a collection
536
- if (paramObj.$Collection) {
560
+ if (paramObj.$Collection && !paramType.items) {
537
561
  csnDefs[boundedEntityName].actions[name].params[paramName] = {};
538
562
  csnDefs[boundedEntityName].actions[name].params[paramName].items = paramType;
539
563
  } else
@@ -542,42 +566,39 @@ function _parseBounded(csnDefs, flag) {
542
566
  let message = '"' + paramObj.$Type + '" is not supported (in element:"' + name + '")';
543
567
  console.log(warn(message));
544
568
  }
545
- }
546
-
547
- }
569
+ }
548
570
  }
549
- //if parameters has no entries
550
- if(csnDefs[boundedEntityName].actions[name].params && Object.keys(csnDefs[boundedEntityName].actions[name].params).length === 0)
551
- {
552
- delete csnDefs[boundedEntityName].actions[name].params;
571
+ }
572
+ //if parameters has no entries
573
+ if (csnDefs[boundedEntityName].actions[name].params && Object.keys(csnDefs[boundedEntityName].actions[name].params).length === 0) {
574
+ delete csnDefs[boundedEntityName].actions[name].params;
575
+ }
576
+ // add returns
577
+ if (obj[j].$ReturnType) {
578
+ let returnType={};
579
+ // check if the return type is pre-defined, undefined or custom defined
580
+ if (edmxncdsdatatype[obj[j].$ReturnType.$Type] || edmxncdsdatatype[obj[j].$ReturnType.$Type + "_a"])
581
+ returnType = generatePropertyCsn(obj[j].$ReturnType, false);
582
+ else {
583
+ let type = _getDatatype(obj[j].$ReturnType.$Type);
584
+ _includeExternalNamespaceAnnotation(obj[j].$ReturnType,returnType);
585
+ if(type) returnType["type"] = type ;
553
586
  }
554
- // add returns
555
- if (obj[j].$ReturnType) {
556
- let returnType={};
557
- // check if the return type is pre-defined, undefined or custom defined
558
- if (edmxncdsdatatype[obj[j].$ReturnType.$Type] || edmxncdsdatatype[obj[j].$ReturnType.$Type + "_a"])
559
- returnType = generatePropertyCsn(obj[j].$ReturnType, false);
560
- else {
561
- let type = _getDatatype(obj[j].$ReturnType.$Type);
562
- _includeExternalNamespaceAnnotation(obj[j].$ReturnType,returnType);
563
- if(type) returnType["type"] = type ;
564
- }
565
- if (returnType.type) {
566
- csnDefs[boundedEntityName].actions[name].returns = {};
567
- // check if return type is a collection
568
- if (obj[j].$ReturnType.$Collection)
569
- csnDefs[boundedEntityName].actions[name].returns.items = returnType;
570
- else
571
- csnDefs[boundedEntityName].actions[name].returns = returnType;
572
- } else {
573
- let message = '"' + obj[j].$ReturnType.$Type + '" is not supported (in return type)';
574
- console.log(warn(message));
575
- }
587
+ if (returnType.type || returnType.items.type) {
588
+ csnDefs[boundedEntityName].actions[name].returns = {};
589
+ // check if return type is a collection
590
+ if (obj[j].$ReturnType.$Collection && !returnType.items)
591
+ csnDefs[boundedEntityName].actions[name].returns.items = returnType;
592
+ else
593
+ csnDefs[boundedEntityName].actions[name].returns = returnType;
594
+ } else {
595
+ let message = '"' + obj[j].$ReturnType.$Type + '" is not supported (in return type)';
596
+ console.log(warn(message));
576
597
  }
577
598
  }
578
599
  }
579
600
  }
580
- );
601
+ });
581
602
  }
582
603
  }
583
604
 
@@ -698,9 +719,10 @@ function _parseUnbounded(schemaData, flag) {
698
719
  const parameterObj = Object.keys(typeProperties).length > 0 ? { type, ...typeProperties } : { type };
699
720
 
700
721
  // check if parameter type is a collection
701
- if (objData.$Parameter[i].$Collection)
722
+ if (objData.$Parameter[i].$Collection && !parameterObj.items) {
723
+ obj[objType].params[objData.$Parameter[i].$Name] = {};
702
724
  obj[objType].params[objData.$Parameter[i].$Name].items = parameterObj;
703
- else
725
+ } else
704
726
  obj[objType].params[objData.$Parameter[i].$Name] = parameterObj;
705
727
 
706
728
  } else {
@@ -710,8 +732,7 @@ function _parseUnbounded(schemaData, flag) {
710
732
  }
711
733
  }
712
734
  //if parameters has no entries
713
- if(obj[objType].params && Object.keys(obj[objType].params).length === 0)
714
- {
735
+ if (obj[objType].params && Object.keys(obj[objType].params).length === 0) {
715
736
  delete obj[objType].params;
716
737
  }
717
738
  // add returns
@@ -725,10 +746,10 @@ function _parseUnbounded(schemaData, flag) {
725
746
  _includeExternalNamespaceAnnotation(objData.$ReturnType,returnValue);
726
747
  if(type) returnValue["type"] = type;
727
748
  }
728
- if (returnValue.type) {
749
+ if (returnValue.type || returnValue.items.type) {
729
750
  obj[objType].returns = {};
730
751
  // check if return type is a collection
731
- if (objData.$ReturnType.$Collection) {
752
+ if (objData.$ReturnType.$Collection && !returnValue.items) {
732
753
  obj[objType].returns.items = {};
733
754
  obj[objType].returns.items = returnValue;
734
755
  } else
@@ -810,10 +831,12 @@ function _generateCSN(edmxAsJson, ignorePersistenceSkip, mockServerUc) {
810
831
  csn.definitions = Object.assign(_parseUnbounded(schemaData , 1), csn.definitions);
811
832
  // Step 4: get all entity type
812
833
  csn.definitions = Object.assign(_parseEntityType(schemaData, ignorePersistenceSkip, mockServerUc), csn.definitions);
813
- // Step 5: get all bounded action & function
834
+ // Step 5: add entity container properties
835
+ csn.definitions = Object.assign(_parseEntityContainer(csn.definitions,schemaData),csn.definitions);
836
+ // Step 6: get all bounded action & function
814
837
  _parseBounded(csn.definitions, 0);
815
838
  _parseBounded(csn.definitions, 1);
816
- // Step 6: get all annotations
839
+ // Step 7: get all annotations
817
840
  _generateDocumentation(schemaData, csn.definitions);
818
841
 
819
842
  return JSON.stringify(csn, null, 4);
@@ -13,8 +13,11 @@ const constants = {
13
13
  OPTION_NODEJS: 'nodejs',
14
14
  OPTION_JAVA: 'java',
15
15
  OPTION_HANA: 'hana',
16
+ OPTION_XSUAA: 'xsuaa',
16
17
  OPTION_MTA: 'mta',
17
18
  OPTION_MTX: 'mtx',
19
+ OPTION_AUDITLOG: 'auditlog',
20
+ OPTION_APPROUTER: 'approuter',
18
21
  OPTION_CF_MANIFEST: 'cf-manifest',
19
22
  OPTION_PIPELINE: 'pipeline',
20
23
  OPTION_SAMPLES: 'samples',
@@ -56,11 +59,14 @@ const constants = {
56
59
  constants.OPTIONS_PRIORITY = [
57
60
  constants.OPTION_JAVA,
58
61
  constants.OPTION_NODEJS,
59
- constants.OPTION_HANA,
60
62
  constants.OPTION_PIPELINE,
61
- constants.OPTION_MTX,
62
- constants.OPTION_CF_MANIFEST,
63
63
  constants.OPTION_MTA,
64
+ constants.OPTION_CF_MANIFEST,
65
+ constants.OPTION_HANA,
66
+ constants.OPTION_XSUAA,
67
+ constants.OPTION_MTX,
68
+ constants.OPTION_AUDITLOG,
69
+ constants.OPTION_APPROUTER,
64
70
  constants.OPTION_SAMPLES,
65
71
  constants.OPTION_NOTEBOOK,
66
72
  constants.OPTION_LINT,
package/lib/init/index.js CHANGED
@@ -7,7 +7,8 @@ const Spinner = require('./util/spinner');
7
7
 
8
8
  const { OPTIONS_PRIORITY, COMMAND_ADD, COMMAND_INIT,
9
9
  // eslint-disable-next-line no-unused-vars
10
- OPTION_HANA, OPTION_JAVA, OPTION_MTA, OPTION_MTX, OPTION_NODEJS,
10
+ OPTION_XSUAA, OPTION_AUDITLOG, OPTION_HANA, OPTION_MTA, OPTION_MTX, OPTION_APPROUTER,
11
+ OPTION_NODEJS, OPTION_JAVA,
11
12
  OPTION_PIPELINE, OPTION_SAMPLES, OPTION_CF_MANIFEST, PROJECT_FILES, REGEX_PROJECT_NAME } = require('./constants');
12
13
 
13
14
  module.exports = class CDSGenerator {
@@ -100,6 +101,7 @@ module.exports = class CDSGenerator {
100
101
  choices: [
101
102
  OPTION_JAVA,
102
103
  OPTION_HANA,
104
+ OPTION_XSUAA,
103
105
  OPTION_PIPELINE,
104
106
  OPTION_CF_MANIFEST,
105
107
  OPTION_MTA,
@@ -180,20 +182,22 @@ module.exports = class CDSGenerator {
180
182
  case COMMAND_INIT: {
181
183
  const relativeProjectPath = path.relative(this.cwd, this.projectPath);
182
184
  const folderName = (relativeProjectPath ? `.${path.sep}${relativeProjectPath}` : 'current folder');
183
- this.logger.log(`creating new project in ${folderName}`);
185
+ this.logger.log(`Creating new cap project in ${folderName}`);
184
186
  break;
185
187
  }
186
188
 
187
189
  case COMMAND_ADD:
188
- this.logger.log(`adding feature(s) to project in current folder`);
190
+ this.logger.log(`Adding feature(s) to project in current folder`);
189
191
  break;
190
192
 
191
193
  default:
192
194
  }
193
195
 
194
196
  if (this.options.force) {
195
- this.logger.log(`using '--force' ... existing files will be overwritten...!`);
197
+ this.logger.log(`Using '--force' ... existing files will be overwritten...!`);
196
198
  }
199
+
200
+ this.logger.log();
197
201
  }
198
202
 
199
203
  async _process() {
@@ -203,7 +207,7 @@ module.exports = class CDSGenerator {
203
207
  await this._fillTemplateList();
204
208
 
205
209
  for (const template of this.templateList) {
206
- const msg = `adding feature '${template.name}'...`;
210
+ const msg = `Adding feature '${template.name}'...`;
207
211
  if (this.logger.isDebug) {
208
212
  this.logger.log(msg);
209
213
  await template.run();
@@ -215,7 +219,7 @@ module.exports = class CDSGenerator {
215
219
  }
216
220
  }
217
221
 
218
- this.logger.log(`done.`);
222
+ this.logger.log(`Done adding features`);
219
223
  this.logger.log();
220
224
  }
221
225
 
@@ -265,12 +269,14 @@ module.exports = class CDSGenerator {
265
269
  for (const template of this.templateList) {
266
270
  await template.finalize();
267
271
  }
272
+
273
+ this.logger.log();
268
274
  }
269
275
 
270
276
  _showFiles() {
271
277
  const files = this.fsUtil.getTouchedFiles();
272
278
  if (files && files.length > 0) {
273
- this.logger.log(`added / changed files`);
279
+ this.logger.log(`Added / changed files`);
274
280
  for (const file of files) {
275
281
  this.logger.log(file);
276
282
  }
@@ -0,0 +1,161 @@
1
+ // This file describes so-called "modules" and "resources" commonly
2
+ // found in mta.yaml files.
3
+ // The following matchers contain the *required* constraints to
4
+ // identify a YAML node as a semantic equivalent of the matcher.
5
+
6
+ const srvNode = {
7
+ ref: "srv",
8
+ keyPath: ["modules"],
9
+ constraints: [{
10
+ comparisonKeyPath: ["type"],
11
+ value: "nodejs"
12
+ }],
13
+ }
14
+
15
+ const srvJava = {
16
+ ref: "srv",
17
+ keyPath: ["modules"],
18
+ constraints: [{
19
+ comparisonKeyPath: ["type"],
20
+ value: "java"
21
+ }],
22
+ }
23
+
24
+ const approuter = {
25
+ ref: "approuter",
26
+ keyPath: ["modules"],
27
+ constraints: [{
28
+ comparisonKeyPath: ["type"],
29
+ value: "approuter.nodejs"
30
+ }],
31
+ spaceBefore: true
32
+ }
33
+
34
+ const xsuaa = {
35
+ ref: "uaa-resource",
36
+ keyPath: ["resources"],
37
+ constraints: [{
38
+ comparisonKeyPath: ["type"],
39
+ value: "org.cloudfoundry.managed-service",
40
+ }, {
41
+ comparisonKeyPath: ["parameters", "service"],
42
+ value: "xsuaa",
43
+ }, {
44
+ comparisonKeyPath: ["parameters", "service-plan"],
45
+ value: "application"
46
+ }],
47
+ spaceBefore: true
48
+ }
49
+
50
+ const auditlog = {
51
+ ref: "auditlog-resource",
52
+ keyPath: ["resources"],
53
+ constraints: [{
54
+ comparisonKeyPath: ["type"],
55
+ value: "org.cloudfoundry.managed-service",
56
+ }, {
57
+ comparisonKeyPath: ["parameters", "service"],
58
+ value: "auditlog-api",
59
+ }],
60
+ spaceBefore: true
61
+ }
62
+
63
+ const hdbDeployer = {
64
+ ref: "deployer",
65
+ keyPath: ["modules"],
66
+ constraints: [{
67
+ comparisonKeyPath: ["type"],
68
+ value: "hdb"
69
+ }],
70
+ spaceBefore: true
71
+ }
72
+
73
+ const hdiContainer = {
74
+ ref: "db-resource",
75
+ keyPath: ["resources"],
76
+ constraints: [{
77
+ comparisonKeyPath: ["type"],
78
+ value: "com.sap.xs.hdi-container",
79
+ }],
80
+ spaceBefore: true
81
+ }
82
+
83
+ const serviceManager = {
84
+ ref: "db-resource",
85
+ keyPath: ["resources"],
86
+ constraints: [{
87
+ comparisonKeyPath: ["type"],
88
+ value: "org.cloudfoundry.managed-service",
89
+ }, {
90
+ comparisonKeyPath: ["parameters", "service"],
91
+ value: "service-manager",
92
+ }, {
93
+ comparisonKeyPath: ["parameters", "service-plan"],
94
+ value: "container"
95
+ }],
96
+ spaceBefore: true
97
+ }
98
+
99
+ const saasRegistry = {
100
+ ref: "registry-resource",
101
+ keyPath: ["resources"],
102
+ constraints: [{
103
+ comparisonKeyPath: ["type"],
104
+ value: "org.cloudfoundry.managed-service",
105
+ }, {
106
+ comparisonKeyPath: ["parameters", "service"],
107
+ value: "saas-registry",
108
+ }, {
109
+ comparisonKeyPath: ["parameters", "service-plan"],
110
+ value: "application"
111
+ }],
112
+ spaceBefore: true
113
+ }
114
+
115
+ const srvAPI = {
116
+ ref: "srvAPI",
117
+ keyPath: ["provides"],
118
+ constraints: [{
119
+ comparisonKeyPath: ["name"],
120
+ value: "srv-api"
121
+ }, {
122
+ comparisonKeyPath: ["properties", "srv-url"],
123
+ value: "${default-url}"
124
+ }]
125
+ }
126
+
127
+ const mtxSidecar = {
128
+ ref: "sidecar",
129
+ keyPath: ["modules"],
130
+ constraints: [{
131
+ comparisonKeyPath: ["type"],
132
+ value: `nodejs`
133
+ }],
134
+ }
135
+
136
+ const mtxAPI = {
137
+ ref: "provided-mtx-api",
138
+ keyPath: ["provides"],
139
+ constraints: [{
140
+ comparisonKeyPath: ["name"],
141
+ value: "mtx-api"
142
+ }, {
143
+ comparisonKeyPath: ["properties", "mtx-url"],
144
+ value: "${default-url}"
145
+ }]
146
+ }
147
+
148
+ module.exports = {
149
+ srvNode,
150
+ srvJava,
151
+ approuter,
152
+ xsuaa,
153
+ auditlog,
154
+ hdbDeployer,
155
+ hdiContainer,
156
+ serviceManager,
157
+ saasRegistry,
158
+ srvAPI,
159
+ mtxSidecar,
160
+ mtxAPI
161
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "destinations": [
3
+ {
4
+ "name": "srv-api",
5
+ "url": "http://localhost:4004",
6
+ "forwardAuthToken": true
7
+ }
8
+ ]
9
+ }
@@ -0,0 +1,48 @@
1
+ ---
2
+ modules:
3
+ - name: {{cap.appName}}-srv
4
+ type: {{cap.pLanguage}}
5
+ requires:
6
+ - name: {{cap.appName}}-uaa
7
+
8
+ - name: {{cap.appName}}
9
+ type: approuter.nodejs
10
+ path: {{& ui.appPath}} # from cds.env.folders. Consider also cds.env.build.target --> gen/app
11
+ parameters:
12
+ keep-existing-routes: true
13
+ disk-quota: 256M
14
+ memory: 256M
15
+ # hosts: # additional tenant specific hostnames (only for Canary)
16
+ ## the developer will do this via an extension descriptor:
17
+ # - <paas-subdomain >${tenant-delimiter}${host}
18
+ # - <saas-subdomain1>${tenant-delimiter}${host}
19
+ # - ...
20
+ {{#cap.isMultitenant}}
21
+ properties:
22
+ TENANT_HOST_PATTERN: "^(.*)-${default-uri}"
23
+ {{/cap.isMultitenant}}
24
+ requires:
25
+ - name: srv-api
26
+ group: destinations
27
+ properties:
28
+ name: srv-api # this is a name which must be used in xs-app.json as well
29
+ url: ~{srv-url}
30
+ forwardAuthToken: true
31
+ {{#cap.isMultitenant}}
32
+ - 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)
33
+ group: destinations
34
+ properties:
35
+ name: mtx-api # this is a name which must be used in xs-app.json as well
36
+ url: ~{mtx-url}
37
+ {{/cap.isMultitenant}}
38
+
39
+ resources:
40
+ - name: {{cap.appName}}-uaa{{#cap.isMultitenant}}-mt{{/cap.isMultitenant}}
41
+ type: org.cloudfoundry.managed-service
42
+ parameters:
43
+ service: xsuaa
44
+ service-plan: application
45
+ path: ./xs-security.json
46
+ config:
47
+ xsappname: {{cap.appName}}-${org}-${space}
48
+ tenant-mode: {{#cap.isMultitenant}}shared{{/cap.isMultitenant}}{{^cap.isMultitenant}}dedicated{{/cap.isMultitenant}}
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "approuter",
3
+ "dependencies": {
4
+ "@sap/approuter": "^10"
5
+ },
6
+ "scripts": {
7
+ "start": "node node_modules/@sap/approuter/approuter.js"
8
+ }
9
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "routes": [
3
+ {
4
+ "source": "^.*$",
5
+ "destination": "srv-api"
6
+ }
7
+ ]
8
+ }
@@ -0,0 +1,66 @@
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_XSUAA } = require('../../constants');
6
+ const { srvNode, srvJava, approuter, xsuaa } = require('../_merging/existences');
7
+
8
+ module.exports = class ApprouterTemplate extends TemplateBase {
9
+ constructor(projectPath, generator) {
10
+ super(projectPath, generator, __dirname);
11
+ this.projectReader = new ProjectReader(this);
12
+ }
13
+
14
+ async getDependencies() {
15
+ return [OPTION_XSUAA];
16
+ }
17
+
18
+ async runMTAMerging() {
19
+ const projectDescriptor = await this.projectReader.read(this.options);
20
+ const mtaYAMLPath = path.join(this.projectPath, 'mta.yaml');
21
+ if (!fse.existsSync(mtaYAMLPath)) return;
22
+ const srv = projectDescriptor.cap.isNodejs ? srvNode : srvJava
23
+ await this.templateUtil.mergeYAML(
24
+ mtaYAMLPath,
25
+ `${__dirname}/files/mta.yaml.hbs`,
26
+ projectDescriptor,
27
+ {
28
+ existences: [srv, approuter, xsuaa],
29
+ relationships: [{
30
+ in: srv.ref,
31
+ inKeyPath: ["requires"],
32
+ into: "name",
33
+ existences: [xsuaa.ref],
34
+ existenceKeyPath: ["name"],
35
+ }, {
36
+ in: approuter.ref,
37
+ inKeyPath: ["requires"],
38
+ into: "name",
39
+ existences: [xsuaa.ref],
40
+ existenceKeyPath: ["name"],
41
+ }],
42
+ }
43
+ );
44
+ }
45
+
46
+ async run() {
47
+ const projectDescriptor = await this.projectReader.read(this.options);
48
+ const appPath = path.join(this.projectPath, projectDescriptor.ui.appPath)
49
+
50
+ await this.templateUtil.mergeJSON(
51
+ `${appPath}/package.json`,
52
+ `${__dirname}/files/package.json`
53
+ );
54
+
55
+ await this.templateUtil.mergeJSON(
56
+ `${appPath}/xs-app.json`,
57
+ `${__dirname}/files/xs-app.json`
58
+ );
59
+
60
+ await this.templateUtil.mergeJSON(
61
+ `${appPath}/default-env.json`,
62
+ `${__dirname}/files/default-env.json`
63
+ );
64
+ await this.runMTAMerging()
65
+ }
66
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "dependencies": {
3
+ "@sap/audit-logging": "^5"
4
+ }
5
+ }
@@ -0,0 +1,13 @@
1
+ ---
2
+ modules:
3
+ - name: {{cap.appName}}-srv
4
+ type: {{cap.pLanguage}}
5
+ requires:
6
+ - name: {{cap.appName}}-auditlog
7
+
8
+ resources:
9
+ - name: {{cap.appName}}-auditlog
10
+ type: org.cloudfoundry.managed-service
11
+ parameters:
12
+ service: auditlog-api
13
+ service-plan: default
@@ -0,0 +1,38 @@
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 { srvNode, srvJava, auditlog } = require('../_merging/existences');
6
+
7
+ module.exports = class AuditlogTemplate extends TemplateBase {
8
+ constructor(projectPath, generator) {
9
+ super(projectPath, generator, __dirname);
10
+ this.projectReader = new ProjectReader(this);
11
+ }
12
+
13
+ async runMTAMerging() {
14
+ const projectDescriptor = await this.projectReader.read(this.options);
15
+ const mtaYAMLPath = path.join(this.projectPath, 'mta.yaml');
16
+ if (!fse.existsSync(mtaYAMLPath)) return;
17
+ const srv = projectDescriptor.cap.isNodejs ? srvNode : srvJava
18
+ await this.templateUtil.mergeYAML(
19
+ mtaYAMLPath,
20
+ `${__dirname}/files/mta.yaml.hbs`,
21
+ projectDescriptor,
22
+ {
23
+ existences: [srv, auditlog],
24
+ relationships: [{
25
+ in: srv.ref,
26
+ inKeyPath: ["requires"],
27
+ into: "name",
28
+ existences: [auditlog.ref],
29
+ existenceKeyPath: ["name"],
30
+ }],
31
+ }
32
+ );
33
+ }
34
+
35
+ async run() {
36
+ await this.runMTAMerging()
37
+ }
38
+ }