@sap/cds-dk 4.7.3 → 4.8.2
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.
- package/CHANGELOG.md +42 -1
- package/bin/activate.js +5 -1
- package/bin/add.js +2 -2
- package/lib/bind/bindingUtil.js +6 -1
- package/lib/client/activate.js +8 -3
- package/lib/client/base_command.js +5 -1
- package/lib/client/helper/cf_helper.js +5 -2
- package/lib/client/params.js +16 -2
- package/lib/client/settings_manager.js +15 -8
- package/lib/compile/openapi/csdl2openapi.js +6 -8
- package/lib/compile/to-xsuaa.js +0 -14
- package/lib/import/utils/MetadataConverter.js +6 -4
- package/lib/import/v2parser.js +59 -35
- package/lib/import/v4parser.js +72 -47
- package/lib/init/constants.js +10 -4
- package/lib/init/index.js +13 -7
- package/lib/init/template/_merging/existences.js +161 -0
- package/lib/init/template/approuter/files/default-env.json +9 -0
- package/lib/init/template/approuter/files/mta.yaml.hbs +48 -0
- package/lib/init/template/approuter/files/package.json +9 -0
- package/lib/init/template/approuter/files/xs-app.json +8 -0
- package/lib/init/template/approuter/index.js +66 -0
- package/lib/init/template/auditlog/files/dependencies.package.json +5 -0
- package/lib/init/template/auditlog/files/mta.yaml.hbs +13 -0
- package/lib/init/template/auditlog/index.js +38 -0
- package/lib/init/template/cf-manifest/index.js +1 -1
- package/lib/init/template/hana/files/mta.yaml.hbs +42 -0
- package/lib/init/template/hana/files/nodejs/dependencies.package.json +5 -0
- package/lib/init/template/hana/index.js +53 -24
- package/lib/init/template/java/index.js +1 -5
- package/lib/init/template/mta/files/mta.yaml.hbs +24 -220
- package/lib/init/template/mta/index.js +25 -17
- package/lib/init/template/mtx/files/cds.package.json +24 -0
- package/lib/init/template/mtx/files/dependencies.package.json +5 -0
- package/lib/init/template/mtx/files/mta.yaml.hbs +74 -0
- package/lib/init/template/mtx/files/xs-security.json.hbs +23 -9
- package/lib/init/template/mtx/index.js +126 -29
- package/lib/init/template/templateBase.js +14 -0
- package/lib/init/template/xsuaa/files/cds.package.json +9 -0
- package/lib/init/template/xsuaa/files/dependencies.package.json +6 -0
- package/lib/init/template/xsuaa/files/mta.yaml.hbs +17 -0
- package/lib/init/template/xsuaa/index.js +75 -0
- package/lib/init/util/fsUtil.js +17 -3
- package/lib/init/util/logger.js +3 -1
- package/lib/init/{template/mta → util}/projectReader.js +26 -11
- package/lib/init/util/templateUtil.js +267 -3
- package/lib/util/exec.d.ts +54 -0
- package/lib/util/exec.js +210 -0
- package/lib/watch/livereload-server.js +43 -31
- package/lib/watch/open.js +1 -1
- package/npm-shrinkwrap.json +3762 -15624
- package/package.json +7 -8
- package/readme.md +1 -1
- package/lib/import/internalDoc/edm2cdsTypeMapping.md +0 -38
- package/lib/init/template/mtx/package/cds.package.json +0 -29
- package/lib/init/template/mtx/package/dependencies.package.json +0 -9
package/lib/import/v4parser.js
CHANGED
|
@@ -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,20 @@ 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][jsonEntityContainerName]).forEach(entry => {
|
|
394
|
+
if(entityCSN[namespace + '.' + entry[0]])
|
|
395
|
+
//Captured the annotations at entity set and entity type name level
|
|
396
|
+
_includeExternalNamespaceAnnotation(entry[1],entityCSN[namespace + '.' + entry[0]]);
|
|
397
|
+
if(entry[0].startsWith('@')){
|
|
398
|
+
//Captured the annotations at entity container name level
|
|
399
|
+
entityCSN[namespace][entry[0]]= entry[1];
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
return entityCSN;
|
|
403
|
+
}
|
|
378
404
|
function _generateEnumType(schemaData) {
|
|
379
405
|
let enumTypeDict = {};
|
|
380
406
|
let temp;
|
|
@@ -531,9 +557,9 @@ function _parseBounded(csnDefs, flag) {
|
|
|
531
557
|
let type = _getDatatype(paramObj.$Type);
|
|
532
558
|
if(type) paramType["type"] = type;
|
|
533
559
|
}
|
|
534
|
-
if (paramType.type) {
|
|
560
|
+
if (paramType.type || paramType.items.type) {
|
|
535
561
|
// check if parameter type is a collection
|
|
536
|
-
if (paramObj.$Collection) {
|
|
562
|
+
if (paramObj.$Collection && !paramType.items) {
|
|
537
563
|
csnDefs[boundedEntityName].actions[name].params[paramName] = {};
|
|
538
564
|
csnDefs[boundedEntityName].actions[name].params[paramName].items = paramType;
|
|
539
565
|
} else
|
|
@@ -542,42 +568,39 @@ function _parseBounded(csnDefs, flag) {
|
|
|
542
568
|
let message = '"' + paramObj.$Type + '" is not supported (in element:"' + name + '")';
|
|
543
569
|
console.log(warn(message));
|
|
544
570
|
}
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
}
|
|
571
|
+
}
|
|
548
572
|
}
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
573
|
+
}
|
|
574
|
+
//if parameters has no entries
|
|
575
|
+
if (csnDefs[boundedEntityName].actions[name].params && Object.keys(csnDefs[boundedEntityName].actions[name].params).length === 0) {
|
|
576
|
+
delete csnDefs[boundedEntityName].actions[name].params;
|
|
577
|
+
}
|
|
578
|
+
// add returns
|
|
579
|
+
if (obj[j].$ReturnType) {
|
|
580
|
+
let returnType={};
|
|
581
|
+
// check if the return type is pre-defined, undefined or custom defined
|
|
582
|
+
if (edmxncdsdatatype[obj[j].$ReturnType.$Type] || edmxncdsdatatype[obj[j].$ReturnType.$Type + "_a"])
|
|
583
|
+
returnType = generatePropertyCsn(obj[j].$ReturnType, false);
|
|
584
|
+
else {
|
|
585
|
+
let type = _getDatatype(obj[j].$ReturnType.$Type);
|
|
586
|
+
_includeExternalNamespaceAnnotation(obj[j].$ReturnType,returnType);
|
|
587
|
+
if(type) returnType["type"] = type ;
|
|
553
588
|
}
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
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
|
-
}
|
|
589
|
+
if (returnType.type || returnType.items.type) {
|
|
590
|
+
csnDefs[boundedEntityName].actions[name].returns = {};
|
|
591
|
+
// check if return type is a collection
|
|
592
|
+
if (obj[j].$ReturnType.$Collection && !returnType.items)
|
|
593
|
+
csnDefs[boundedEntityName].actions[name].returns.items = returnType;
|
|
594
|
+
else
|
|
595
|
+
csnDefs[boundedEntityName].actions[name].returns = returnType;
|
|
596
|
+
} else {
|
|
597
|
+
let message = '"' + obj[j].$ReturnType.$Type + '" is not supported (in return type)';
|
|
598
|
+
console.log(warn(message));
|
|
576
599
|
}
|
|
577
600
|
}
|
|
578
601
|
}
|
|
579
602
|
}
|
|
580
|
-
);
|
|
603
|
+
});
|
|
581
604
|
}
|
|
582
605
|
}
|
|
583
606
|
|
|
@@ -698,9 +721,10 @@ function _parseUnbounded(schemaData, flag) {
|
|
|
698
721
|
const parameterObj = Object.keys(typeProperties).length > 0 ? { type, ...typeProperties } : { type };
|
|
699
722
|
|
|
700
723
|
// check if parameter type is a collection
|
|
701
|
-
if (objData.$Parameter[i].$Collection)
|
|
724
|
+
if (objData.$Parameter[i].$Collection && !parameterObj.items) {
|
|
725
|
+
obj[objType].params[objData.$Parameter[i].$Name] = {};
|
|
702
726
|
obj[objType].params[objData.$Parameter[i].$Name].items = parameterObj;
|
|
703
|
-
else
|
|
727
|
+
} else
|
|
704
728
|
obj[objType].params[objData.$Parameter[i].$Name] = parameterObj;
|
|
705
729
|
|
|
706
730
|
} else {
|
|
@@ -710,8 +734,7 @@ function _parseUnbounded(schemaData, flag) {
|
|
|
710
734
|
}
|
|
711
735
|
}
|
|
712
736
|
//if parameters has no entries
|
|
713
|
-
if(obj[objType].params && Object.keys(obj[objType].params).length === 0)
|
|
714
|
-
{
|
|
737
|
+
if (obj[objType].params && Object.keys(obj[objType].params).length === 0) {
|
|
715
738
|
delete obj[objType].params;
|
|
716
739
|
}
|
|
717
740
|
// add returns
|
|
@@ -725,10 +748,10 @@ function _parseUnbounded(schemaData, flag) {
|
|
|
725
748
|
_includeExternalNamespaceAnnotation(objData.$ReturnType,returnValue);
|
|
726
749
|
if(type) returnValue["type"] = type;
|
|
727
750
|
}
|
|
728
|
-
if (returnValue.type) {
|
|
751
|
+
if (returnValue.type || returnValue.items.type) {
|
|
729
752
|
obj[objType].returns = {};
|
|
730
753
|
// check if return type is a collection
|
|
731
|
-
if (objData.$ReturnType.$Collection) {
|
|
754
|
+
if (objData.$ReturnType.$Collection && !returnValue.items) {
|
|
732
755
|
obj[objType].returns.items = {};
|
|
733
756
|
obj[objType].returns.items = returnValue;
|
|
734
757
|
} else
|
|
@@ -810,10 +833,12 @@ function _generateCSN(edmxAsJson, ignorePersistenceSkip, mockServerUc) {
|
|
|
810
833
|
csn.definitions = Object.assign(_parseUnbounded(schemaData , 1), csn.definitions);
|
|
811
834
|
// Step 4: get all entity type
|
|
812
835
|
csn.definitions = Object.assign(_parseEntityType(schemaData, ignorePersistenceSkip, mockServerUc), csn.definitions);
|
|
813
|
-
// Step 5:
|
|
836
|
+
// Step 5: add entity container properties
|
|
837
|
+
csn.definitions = Object.assign(_parseEntityContainer(csn.definitions,schemaData),csn.definitions);
|
|
838
|
+
// Step 6: get all bounded action & function
|
|
814
839
|
_parseBounded(csn.definitions, 0);
|
|
815
840
|
_parseBounded(csn.definitions, 1);
|
|
816
|
-
// Step
|
|
841
|
+
// Step 7: get all annotations
|
|
817
842
|
_generateDocumentation(schemaData, csn.definitions);
|
|
818
843
|
|
|
819
844
|
return JSON.stringify(csn, null, 4);
|
package/lib/init/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const os = require('os');
|
|
2
2
|
|
|
3
|
-
const MAVEN_ARCHETYPE_VERSION = '1.
|
|
3
|
+
const MAVEN_ARCHETYPE_VERSION = '1.22.1';
|
|
4
4
|
|
|
5
5
|
const constants = {
|
|
6
6
|
IS_WIN: (os.platform() === 'win32'),
|
|
@@ -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
|
-
|
|
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(`
|
|
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(`
|
|
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(`
|
|
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 = `
|
|
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(`
|
|
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(`
|
|
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,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,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,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
|