@sap/cds-dk 4.7.1 → 4.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +49 -0
- 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 +70 -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/util/mvnArchetypeUtil.js +3 -1
- package/lib/init/{template/mta → util}/projectReader.js +26 -11
- package/lib/init/util/templateUtil.js +267 -3
- package/lib/lint/Linter.js +0 -1
- package/lib/lint/io.js +2 -2
- 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 +3819 -16606
- 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,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
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
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
|
-
|
|
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
|
-
}
|
|
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:
|
|
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
|
|
839
|
+
// Step 7: get all annotations
|
|
817
840
|
_generateDocumentation(schemaData, csn.definitions);
|
|
818
841
|
|
|
819
842
|
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.0';
|
|
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
|