@sap/cds-dk 8.0.2 → 8.1.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.
- package/CHANGELOG.md +49 -3
- package/bin/bind.js +3 -3
- package/bin/cds.js +8 -7
- package/bin/init.js +3 -6
- package/bin/version.js +5 -3
- package/bin/watch.js +12 -4
- package/lib/build/constants.js +1 -0
- package/lib/build/provider/hana/index.js +54 -37
- package/lib/build/provider/internalBuildTaskProvider.js +2 -2
- package/lib/build/provider/mtx-sidecar/index.js +10 -3
- package/lib/build/provider/nodejs/index.js +4 -3
- package/lib/compile/to-mermaid.js +27 -12
- package/lib/deploy/to-hana/hana.js +10 -8
- package/lib/deploy/to-hana/hdiDeployUtil.js +9 -1
- package/lib/init/constants.js +13 -3
- package/lib/init/index.js +6 -4
- package/lib/init/projectReader.js +3 -4
- package/lib/init/template/audit-logging/files/package.sidecar.json +7 -0
- package/lib/init/template/audit-logging/index.js +1 -1
- package/lib/init/template/cf-manifest/index.js +4 -0
- package/lib/init/template/cov2ap/files/dependencies.package.json +5 -0
- package/lib/init/template/cov2ap/index.js +31 -0
- package/lib/init/template/data/as-json.js +25 -11
- package/lib/init/template/destination/files/mta.yaml.hbs +6 -0
- package/lib/init/template/destination/files/package.sidecar.json +7 -0
- package/lib/init/template/destination/index.js +12 -2
- package/lib/init/template/event-queue/files/dependencies.package.json +5 -0
- package/lib/init/template/event-queue/index.js +35 -0
- package/lib/init/template/html5-repo/files/mta.yaml.hbs +6 -58
- package/lib/init/template/html5-repo/files/package.sidecar.json +7 -0
- package/lib/init/template/html5-repo/files/xs-app.json.hbs +1 -15
- package/lib/init/template/html5-repo/index.js +13 -10
- package/lib/init/template/http/index.js +37 -28
- package/lib/init/template/malware-scanner/index.js +1 -1
- package/lib/init/template/mta/files/package.json +1 -1
- package/lib/init/template/redis/files/mta.yaml.hbs +25 -0
- package/lib/init/template/redis/files/package.json.hbs +5 -0
- package/lib/init/template/redis/index.js +44 -0
- package/lib/init/template/redis-messaging/files/package.json.hbs +0 -3
- package/lib/init/template/redis-messaging/index.js +4 -18
- package/lib/init/template/sample/files/app/admin-books/webapp/manifest.json +0 -1
- package/lib/init/template/sample/files/app/browse/webapp/manifest.json +0 -1
- package/lib/init/template/sample/files/nodejs/admin-service.js +13 -8
- package/lib/init/template/sample/files/nodejs/cat-service.js +27 -15
- package/lib/init/template/typescript/files/package.json +3 -3
- package/lib/init/template/websocket/files/dependencies.package.json +5 -0
- package/lib/init/template/websocket/index.js +35 -0
- package/lib/init/template/workzone/index.js +1 -0
- package/lib/init/template/workzone-standard/files/mta.yaml.hbs +59 -0
- package/lib/init/template/workzone-standard/index.js +24 -8
- package/npm-shrinkwrap.json +22 -19
- package/package.json +1 -1
- package/lib/init/template/redis-messaging/files/mta.yaml.hbs +0 -14
|
@@ -59,7 +59,15 @@ module.exports = new class HdiDeployUtil {
|
|
|
59
59
|
Add it either to ${bold('devDependencies')} using 'npm install -D ${HDI_DEPLOY_LIB}' or install it globally using 'npm install -g ${HDI_DEPLOY_LIB}'.`);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
console.log(`
|
|
62
|
+
console.log(`HDI deployer path: ${libPath}`)
|
|
63
|
+
|
|
64
|
+
const libRoot = path.dirname(libPath);
|
|
65
|
+
try {
|
|
66
|
+
const libPackageJson = require(path.join(libRoot, 'package.json'));
|
|
67
|
+
console.log(`HDI deployer version: ${libPackageJson.version}`);
|
|
68
|
+
} catch {
|
|
69
|
+
// ignore
|
|
70
|
+
}
|
|
63
71
|
|
|
64
72
|
// let any error go through and abort deploy
|
|
65
73
|
return require(libPath);
|
package/lib/init/constants.js
CHANGED
|
@@ -5,9 +5,10 @@ module.exports = {
|
|
|
5
5
|
COMMAND_ADD: 'add',
|
|
6
6
|
|
|
7
7
|
JAVA_LTS_VERSIONS: [17, 21],
|
|
8
|
-
MAVEN_ARCHETYPE_VERSION: '
|
|
8
|
+
MAVEN_ARCHETYPE_VERSION: '3.0.1',
|
|
9
9
|
|
|
10
10
|
OPTIONS: Object.freeze({
|
|
11
|
+
COMPLETION: 'completion',
|
|
11
12
|
JAVA: 'java',
|
|
12
13
|
JAVA_MVN: 'java:mvn',
|
|
13
14
|
JAVA_PACKAGE: 'java:package',
|
|
@@ -30,6 +31,9 @@ module.exports = {
|
|
|
30
31
|
SQLITE: 'sqlite',
|
|
31
32
|
H2: 'h2',
|
|
32
33
|
LIQUIBASE: 'liquibase',
|
|
34
|
+
REDIS: 'redis',
|
|
35
|
+
ATTACHMENTS: 'attachments',
|
|
36
|
+
MALWARE_SCANNER: 'malware-scanner',
|
|
33
37
|
LOCAL_MESSAGING: 'local-messaging',
|
|
34
38
|
FILE_BASED_MESSAGING: 'file-based-messaging',
|
|
35
39
|
ENTERPRISE_MESSAGING: 'enterprise-messaging',
|
|
@@ -53,7 +57,10 @@ module.exports = {
|
|
|
53
57
|
LINT_DEV: 'lint:dev',
|
|
54
58
|
PIPELINE: 'pipeline',
|
|
55
59
|
TYPER: 'typer',
|
|
56
|
-
TYPESCRIPT: 'typescript'
|
|
60
|
+
TYPESCRIPT: 'typescript',
|
|
61
|
+
EVENT_QUEUE: 'event-queue',
|
|
62
|
+
COV2AP: 'cov2ap',
|
|
63
|
+
WEBSOCKET: 'websocket'
|
|
57
64
|
}),
|
|
58
65
|
|
|
59
66
|
REGEX_JAVA_PACKAGE: /^[a-z_][a-z0-9_]*(\.[a-z_][a-z0-9_]*)*$/g,
|
|
@@ -65,7 +72,10 @@ module.exports = {
|
|
|
65
72
|
SAMPLES: 'https://github.com/SAP-samples/cloud-cap-samples',
|
|
66
73
|
CAPIRE: 'https://cap.cloud.sap',
|
|
67
74
|
MAVEN_ARCHETYPE_HELP: `https://cap.cloud.sap/docs/java/developing-applications/building#the-maven-archetype`,
|
|
68
|
-
MAVEN_INSTALL_HELP: `https://maven.apache.org/install.html
|
|
75
|
+
MAVEN_INSTALL_HELP: `https://maven.apache.org/install.html`,
|
|
76
|
+
CAP_JS_COMMUNITY_ODATA_V2: 'https://github.com/cap-js-community/odata-v2-adapter',
|
|
77
|
+
CAP_JS_COMMUNITY_EVENT_QUEUE: 'https://github.com/cap-js-community/event-queue',
|
|
78
|
+
CAP_JS_COMMUNITY_WEBSOCKET: 'https://github.com/cap-js-community/websocket'
|
|
69
79
|
}),
|
|
70
80
|
|
|
71
81
|
PROJECT_FILES: ['package.json', 'pom.xml', '.cdsrc.json']
|
package/lib/init/index.js
CHANGED
|
@@ -22,14 +22,16 @@ module.exports = class CDSGenerator {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
static help({ exclude = [] } = {}) {
|
|
25
|
+
if (!cds.add) return // use case shell completion: cds.add is undefined and not needed
|
|
26
|
+
|
|
25
27
|
const plugins = this.readPlugins(exclude)
|
|
26
28
|
const nameFixedLength = Math.max(...plugins.map(plugin => plugin.name.length))
|
|
27
29
|
return plugins
|
|
30
|
+
.filter(({module}) => module.help())
|
|
28
31
|
.map(({name, module}) => {
|
|
29
|
-
|
|
30
|
-
return ` *${name}*${' '.repeat(nameFixedLength - name.length)} - ${help}`
|
|
32
|
+
return ` *${name}*${' '.repeat(nameFixedLength - name.length)} - ${module.help()}`
|
|
31
33
|
})
|
|
32
|
-
.join('\n
|
|
34
|
+
.join('\n')
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
/**
|
|
@@ -176,7 +178,7 @@ module.exports = class CDSGenerator {
|
|
|
176
178
|
const fuzzySearch = require('../../bin/util/fuzzySearch')
|
|
177
179
|
const [bestMatch] = fuzzySearch(plugin, entries.map(e => e.name))
|
|
178
180
|
const max = entries.reduce((max, {name}) => Math.max(max, name.length), 0)
|
|
179
|
-
const allFacetsText = entries.map(({name, module}) => {
|
|
181
|
+
const allFacetsText = entries.filter(({module})=> module.help()).map(({name, module}) => {
|
|
180
182
|
const help = module.help?.() ?? ''
|
|
181
183
|
return `${term.bold(name) + ' '.repeat(max - name.length)} ${term.dim(help)}`
|
|
182
184
|
}).join('\n')
|
|
@@ -4,6 +4,7 @@ const { fs, exists, isdir, path } = cds.utils
|
|
|
4
4
|
const { parseXml } = require('./xml')
|
|
5
5
|
const { REGEX_JAVA_VERSION, JAVA_LTS_VERSIONS } = require('./constants')
|
|
6
6
|
const DEBUG = cds.debug('cli')
|
|
7
|
+
const TRACE = cds.debug('trace')
|
|
7
8
|
|
|
8
9
|
module.exports = new class ProjectReader {
|
|
9
10
|
|
|
@@ -41,7 +42,6 @@ module.exports = new class ProjectReader {
|
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
// REVISIT: There should an API provided by cds.env
|
|
45
45
|
/**
|
|
46
46
|
* Returns cds.env using 'production' profile by default as mta deployment is executed with having production profile set.
|
|
47
47
|
*/
|
|
@@ -89,7 +89,7 @@ module.exports = new class ProjectReader {
|
|
|
89
89
|
* @property {boolean} hasAttachments Indicates if the project uses SAP BTP Object Store Service.
|
|
90
90
|
* @property {boolean} hasApprouter Indicates if the project uses the SAP Application Router.
|
|
91
91
|
* @property {boolean} hasHtml5Repo Indicates if the project uses the SAP BTP HTML5 Application Repository.
|
|
92
|
-
* @property {boolean} hasPortal Indicates if the project uses the SAP Cloud Portal
|
|
92
|
+
* @property {boolean} hasPortal Indicates if the project uses the SAP Cloud Portal service.
|
|
93
93
|
* @property {boolean} hasDestination Indicates if the project uses the SAP BTP Destination service.
|
|
94
94
|
* @property {boolean} hasMTXRoute Indicates if the approuter should have a multitenant route.
|
|
95
95
|
* @property {boolean} hasMTXRouteJava Indicates if the approuter should have a multitenant subscription route (java).
|
|
@@ -107,7 +107,7 @@ module.exports = new class ProjectReader {
|
|
|
107
107
|
if (!this.appName) this.#setPackageInfo()
|
|
108
108
|
const env = this.env4('production')
|
|
109
109
|
const { appVersion, appName, appId, appDescription, jdkVersion } = this
|
|
110
|
-
|
|
110
|
+
TRACE?.({ env })
|
|
111
111
|
|
|
112
112
|
const _inProd = plugin => require(`./template/${plugin}`).hasInProduction(env)
|
|
113
113
|
const _ui5 = () => exists('package.json') && !!JSON.parse(fs.readFileSync(path.resolve(cds.root, 'package.json'))).sapux
|
|
@@ -188,7 +188,6 @@ module.exports = new class ProjectReader {
|
|
|
188
188
|
})
|
|
189
189
|
})()
|
|
190
190
|
|
|
191
|
-
DEBUG?.({ project })
|
|
192
191
|
return project
|
|
193
192
|
}
|
|
194
193
|
}
|
|
@@ -36,7 +36,7 @@ module.exports = class AuditLoggingTemplate extends require('../../plugin') {
|
|
|
36
36
|
const { hasMta, hasHelm, hasMultitenancy, srvPath } = project
|
|
37
37
|
const { plan = 'premium' } = cds.cli.options
|
|
38
38
|
project.servicePlan = plan
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
if (hasMultitenancy) {
|
|
41
41
|
await merge(__dirname, 'files/package.sidecar.json').into('mtx/sidecar/package.json')
|
|
42
42
|
}
|
|
@@ -12,6 +12,10 @@ module.exports = class CfManifestTemplate extends require('../../plugin') {
|
|
|
12
12
|
return 'Cloud Foundry deployment using manifest files'
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
static hasInProduction() {
|
|
16
|
+
return exists(MANIFEST_FILE)
|
|
17
|
+
}
|
|
18
|
+
|
|
15
19
|
async canRun() {
|
|
16
20
|
if (cds.cli.options.force) {
|
|
17
21
|
return true
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const { readProject } = require('../../projectReader')
|
|
2
|
+
const { merge, sort } = require('../../merge')
|
|
3
|
+
const { link } = require('../../../util/term')
|
|
4
|
+
const { CAP_JS_COMMUNITY_ODATA_V2 } = require('../../constants').URLS
|
|
5
|
+
|
|
6
|
+
module.exports = class Cov2apTemplate extends require('../../plugin') {
|
|
7
|
+
|
|
8
|
+
static help() {
|
|
9
|
+
return 'cap-js-community: expose CDS services via the OData V2 protocol'
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static hasInProduction() {
|
|
13
|
+
const { dependencies } = readProject()
|
|
14
|
+
return !!dependencies?.['@cap-js-community/odata-v2-adapter']
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async canRun() {
|
|
18
|
+
const { isJava } = readProject()
|
|
19
|
+
if (isJava) throw `'cds add cov2ap' is not available for Java`
|
|
20
|
+
return true
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async run() {
|
|
24
|
+
await merge(__dirname, 'files/dependencies.package.json').into('package.json')
|
|
25
|
+
await sort('package.json', 'dependencies')
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async finalize() {
|
|
29
|
+
console.log(`Find plugin documentation on ${link(CAP_JS_COMMUNITY_ODATA_V2)}`)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -3,7 +3,7 @@ const { dirname } = require('node:path')
|
|
|
3
3
|
const cds = require('../../../cds')
|
|
4
4
|
|
|
5
5
|
let counter = Math.round(Math.random() * 10000) // Default random seed // Non-deterministic behaviour
|
|
6
|
-
const MAX_ASSOC_DEPTH =
|
|
6
|
+
const MAX_ASSOC_DEPTH = 5
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Creates JSON test data for the given entities
|
|
@@ -40,25 +40,35 @@ const asJson = module.exports = async (data, csn, numRecords=1, options={}) => {
|
|
|
40
40
|
|
|
41
41
|
for (const name of entityNames) {
|
|
42
42
|
if (!data[name] // removed on purpose because records are created inline through compositions
|
|
43
|
-
|| data[name].length >= numRecords) { // already created by following associations
|
|
43
|
+
|| data[name].length >= numRecords) { // numRecords already created by following associations
|
|
44
44
|
continue
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
let numRecordsToGenerate // numRecords might be reduced if some records were created by following associations
|
|
48
|
+
let records = []
|
|
49
|
+
if (data[name].length > 0) {
|
|
50
|
+
numRecordsToGenerate = numRecords - data[name].length
|
|
51
|
+
records = Array(numRecordsToGenerate).fill({}).map(() => ({}))
|
|
52
|
+
} else {
|
|
53
|
+
numRecordsToGenerate = numRecords
|
|
54
|
+
records = data[name] = Array(numRecordsToGenerate).fill({}).map(() => ({}))
|
|
55
|
+
}
|
|
48
56
|
const entity = defs[name]
|
|
49
57
|
|
|
50
58
|
const idNum = randomNumber()
|
|
51
|
-
for (let i = 0; i <
|
|
59
|
+
for (let i = 0; i < numRecordsToGenerate; i++) {
|
|
52
60
|
fillRecord(records[i], idNum+i, entity, csn, data, null, 0, referenceData)
|
|
53
61
|
}
|
|
54
|
-
|
|
55
|
-
|
|
62
|
+
data[name] = data[name].concat(records) // append the new records to the possibly existingand referenced records
|
|
63
|
+
// remove records w/ duplicate keys. This can happen if the key is an enum (and we have less enum values than requested records).
|
|
64
|
+
data[name] = uniqRecords(data[name], entity)
|
|
56
65
|
}
|
|
57
66
|
return data
|
|
58
67
|
}
|
|
59
68
|
|
|
60
69
|
function fillRecord(record, recordID, entity, csn, data, parentEntity, depth, referenceData) {
|
|
61
70
|
Object.defineProperty(record, '$id', {value: recordID, enumerable: false})
|
|
71
|
+
if (data[entity.name]) data[entity.name].push(record) // add id to data, to be referenced by associations to prevent circular dependencies
|
|
62
72
|
|
|
63
73
|
const { elements } = entity
|
|
64
74
|
Object.values(elements).sort(asJson.elementsSorter(csn)).forEach(el => {
|
|
@@ -242,7 +252,7 @@ function dataForField(element, entity, csn, record, data, parentEntity, depth, r
|
|
|
242
252
|
if (element.is2many)
|
|
243
253
|
return
|
|
244
254
|
const target = csn.definitions[element.target]
|
|
245
|
-
if (!target ||
|
|
255
|
+
if (!target || depth > MAX_ASSOC_DEPTH)
|
|
246
256
|
return
|
|
247
257
|
|
|
248
258
|
let targetRecord = randomFromReferenceData(target, csn, referenceData)
|
|
@@ -256,10 +266,14 @@ function dataForField(element, entity, csn, record, data, parentEntity, depth, r
|
|
|
256
266
|
targetRecords = data[target.name] = []
|
|
257
267
|
else if (!targetRecords) // target entity is not in the list of entities to be created
|
|
258
268
|
return
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
269
|
+
|
|
270
|
+
if (targetRecords.length > 0) { // use record generated by following asociation
|
|
271
|
+
targetRecord = targetRecords[0]
|
|
272
|
+
} else {
|
|
273
|
+
targetRecord = fillRecord({}, randomNumber(), target, csn, data, entity, depth+1, referenceData)
|
|
274
|
+
targetRecords.push(targetRecord)
|
|
275
|
+
uniqRecords(targetRecords, target)
|
|
276
|
+
}
|
|
263
277
|
}
|
|
264
278
|
|
|
265
279
|
// TODO: handle foreign keys correctly
|
|
@@ -11,6 +11,12 @@ modules:
|
|
|
11
11
|
requires:
|
|
12
12
|
- name: {{appName}}-destination
|
|
13
13
|
|
|
14
|
+
- name: {{appName}}-mtx
|
|
15
|
+
type: nodejs
|
|
16
|
+
path: {{#isNodejs}}gen/{{/isNodejs}}mtx/sidecar
|
|
17
|
+
requires:
|
|
18
|
+
- name: {{appName}}-destination
|
|
19
|
+
|
|
14
20
|
resources:
|
|
15
21
|
- name: {{appName}}-destination
|
|
16
22
|
type: org.cloudfoundry.managed-service
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const { readProject } = require('../../projectReader')
|
|
2
2
|
const { merge } = require('../../merge')
|
|
3
|
-
const { srv4, approuter, destination } = require('../../registries/mta')
|
|
3
|
+
const { srv4, approuter, destination, mtxSidecar4 } = require('../../registries/mta')
|
|
4
4
|
|
|
5
5
|
module.exports = class DestinationTemplate extends require('../../plugin') {
|
|
6
6
|
|
|
@@ -24,7 +24,11 @@ module.exports = class DestinationTemplate extends require('../../plugin') {
|
|
|
24
24
|
|
|
25
25
|
async combine() {
|
|
26
26
|
const project = readProject()
|
|
27
|
-
const { hasHelm, hasApprouter, hasHelmUnifiedRuntime, hasMta, srvPath } = project
|
|
27
|
+
const { hasHelm, hasApprouter, hasMultitenancy, hasHelmUnifiedRuntime, hasMta, srvPath, isJava } = project
|
|
28
|
+
|
|
29
|
+
if (hasMultitenancy) {
|
|
30
|
+
await merge(__dirname, 'files/package.sidecar.json').into('mtx/sidecar/package.json')
|
|
31
|
+
}
|
|
28
32
|
|
|
29
33
|
if (hasMta) {
|
|
30
34
|
const srv = srv4(srvPath)
|
|
@@ -39,6 +43,12 @@ module.exports = class DestinationTemplate extends require('../../plugin') {
|
|
|
39
43
|
into: [approuter, 'requires', 'name']
|
|
40
44
|
})
|
|
41
45
|
}
|
|
46
|
+
if (hasMultitenancy) {
|
|
47
|
+
relationships.push({
|
|
48
|
+
insert: [destination, 'name'],
|
|
49
|
+
into: [mtxSidecar4(isJava ? 'mtx/sidecar' : 'gen/mtx/sidecar'), 'requires', 'name']
|
|
50
|
+
})
|
|
51
|
+
}
|
|
42
52
|
await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', { with: project, additions, relationships })
|
|
43
53
|
}
|
|
44
54
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const { readProject } = require('../../projectReader')
|
|
2
|
+
const { merge, sort } = require('../../merge')
|
|
3
|
+
const { link } = require('../../../util/term')
|
|
4
|
+
const { CAP_JS_COMMUNITY_EVENT_QUEUE } = require('../../constants').URLS
|
|
5
|
+
|
|
6
|
+
module.exports = class EventQueueTemplate extends require('../../plugin') {
|
|
7
|
+
|
|
8
|
+
static help() {
|
|
9
|
+
return 'cap-js-community: transactional event processing with automatic load distribution'
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async canRun() {
|
|
13
|
+
const { isJava } = readProject()
|
|
14
|
+
if (isJava) throw `'cds add event-queue' is not available for Java`
|
|
15
|
+
return true
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static hasInProduction() {
|
|
19
|
+
const { dependencies } = readProject()
|
|
20
|
+
return !!dependencies?.['@cap-js-community/event-queue']
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
requires() {
|
|
24
|
+
return ['redis']
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async run() {
|
|
28
|
+
await merge(__dirname, 'files/dependencies.package.json').into('package.json')
|
|
29
|
+
await sort('package.json', 'dependencies')
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async finalize() {
|
|
33
|
+
console.log(`Find plugin documentation on ${link(CAP_JS_COMMUNITY_EVENT_QUEUE)}`)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -12,6 +12,12 @@ modules:
|
|
|
12
12
|
requires:
|
|
13
13
|
- name: {{appName}}-html5-runtime
|
|
14
14
|
|
|
15
|
+
- name: {{appName}}-mtx
|
|
16
|
+
type: nodejs
|
|
17
|
+
path: {{#isNodejs}}gen/{{/isNodejs}}mtx/sidecar
|
|
18
|
+
requires:
|
|
19
|
+
- name: {{appName}}-html5-runtime
|
|
20
|
+
|
|
15
21
|
- name: {{appName}}-app-deployer
|
|
16
22
|
type: com.sap.application.content
|
|
17
23
|
path: {{#isNodejs}}gen{{/isNodejs}}{{#isJava}}.{{/isJava}}
|
|
@@ -42,38 +48,6 @@ modules:
|
|
|
42
48
|
supported-platforms: []
|
|
43
49
|
{{/apps}}
|
|
44
50
|
|
|
45
|
-
- name: {{appName}}-destinations
|
|
46
|
-
type: com.sap.application.content
|
|
47
|
-
requires:
|
|
48
|
-
- name: {{appName}}-auth
|
|
49
|
-
parameters:
|
|
50
|
-
service-key:
|
|
51
|
-
name: {{appName}}-auth-key
|
|
52
|
-
- name: {{appName}}-html5-repo-host
|
|
53
|
-
parameters:
|
|
54
|
-
service-key:
|
|
55
|
-
name: {{appName}}-html5-repo-host-key
|
|
56
|
-
- name: srv-api
|
|
57
|
-
- name: {{appName}}-destination
|
|
58
|
-
parameters:
|
|
59
|
-
content-target: true
|
|
60
|
-
build-parameters:
|
|
61
|
-
no-source: true
|
|
62
|
-
parameters:
|
|
63
|
-
content:
|
|
64
|
-
instance:
|
|
65
|
-
existing_destinations_policy: update
|
|
66
|
-
destinations:
|
|
67
|
-
- Name: {{appName}}-html5-repository
|
|
68
|
-
ServiceInstanceName: {{appName}}-html5-repo-host
|
|
69
|
-
ServiceKeyName: {{appName}}-html5-repo-host-key
|
|
70
|
-
sap.cloud.service: {{appName}}.service
|
|
71
|
-
- Name: {{appName}}-auth
|
|
72
|
-
Authentication: OAuth2UserTokenExchange
|
|
73
|
-
ServiceInstanceName: {{appName}}-auth
|
|
74
|
-
ServiceKeyName: {{appName}}-auth-key
|
|
75
|
-
sap.cloud.service: {{appName}}.service
|
|
76
|
-
|
|
77
51
|
resources:
|
|
78
52
|
{{#hasApprouter}}
|
|
79
53
|
- name: {{appName}}-html5-runtime
|
|
@@ -88,29 +62,3 @@ resources:
|
|
|
88
62
|
parameters:
|
|
89
63
|
service: html5-apps-repo
|
|
90
64
|
service-plan: app-host
|
|
91
|
-
|
|
92
|
-
- name: {{appName}}-destination
|
|
93
|
-
type: org.cloudfoundry.managed-service
|
|
94
|
-
parameters:
|
|
95
|
-
service: destination
|
|
96
|
-
service-plan: lite
|
|
97
|
-
config:
|
|
98
|
-
HTML5Runtime_enabled: true
|
|
99
|
-
init_data:
|
|
100
|
-
instance:
|
|
101
|
-
existing_destinations_policy: update
|
|
102
|
-
destinations:
|
|
103
|
-
- Name: {{appName}}-srv-api
|
|
104
|
-
URL: ~{srv-api/srv-url}
|
|
105
|
-
Authentication: NoAuthentication
|
|
106
|
-
Type: HTTP
|
|
107
|
-
ProxyType: Internet
|
|
108
|
-
HTML5.ForwardAuthToken: true
|
|
109
|
-
HTML5.DynamicDestination: true
|
|
110
|
-
requires:
|
|
111
|
-
- name: srv-api
|
|
112
|
-
group: destinations
|
|
113
|
-
properties:
|
|
114
|
-
name: srv-api # must be used in xs-app.json as well
|
|
115
|
-
url: ~{srv-url}
|
|
116
|
-
forwardAuthToken: true
|
|
@@ -4,24 +4,10 @@
|
|
|
4
4
|
{
|
|
5
5
|
"source": "^/?odata/(.*)$",
|
|
6
6
|
"target": "/odata/$1",
|
|
7
|
-
"destination": "
|
|
7
|
+
"destination": "srv-api",
|
|
8
8
|
{{#hasXsuaa}}"authenticationType": "xsuaa",{{/hasXsuaa}}
|
|
9
9
|
"csrfProtection": true
|
|
10
10
|
},
|
|
11
|
-
{{#hasUI5}}
|
|
12
|
-
{
|
|
13
|
-
"source": "^/resources/(.*)$",
|
|
14
|
-
"target": "/resources/$1",
|
|
15
|
-
"authenticationType": "none",
|
|
16
|
-
"destination": "ui5"
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
"source": "^/test-resources/(.*)$",
|
|
20
|
-
"target": "/test-resources/$1",
|
|
21
|
-
"authenticationType": "none",
|
|
22
|
-
"destination": "ui5"
|
|
23
|
-
},
|
|
24
|
-
{{/hasUI5}}
|
|
25
11
|
{
|
|
26
12
|
"source": "^(.*)$",
|
|
27
13
|
"target": "$1",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { join } = require('path')
|
|
2
2
|
const { readProject } = require('../../projectReader')
|
|
3
3
|
const { merge } = require('../../merge')
|
|
4
|
-
const { srv4,
|
|
4
|
+
const { srv4, html5RepoHost, html5Runtime, appDeployer, approuter, mtxSidecar4 } = require('../../registries/mta')
|
|
5
5
|
|
|
6
6
|
module.exports = class Html5RepoTemplate extends require('../../plugin') {
|
|
7
7
|
|
|
@@ -9,10 +9,6 @@ module.exports = class Html5RepoTemplate extends require('../../plugin') {
|
|
|
9
9
|
return 'SAP BTP HTML5 Application Repository'
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
requires() {
|
|
13
|
-
return ['destination']
|
|
14
|
-
}
|
|
15
|
-
|
|
16
12
|
static hasInProduction(env) {
|
|
17
13
|
return !!env.requires['html5-repo']
|
|
18
14
|
}
|
|
@@ -47,13 +43,17 @@ module.exports = class Html5RepoTemplate extends require('../../plugin') {
|
|
|
47
43
|
|
|
48
44
|
async combine() {
|
|
49
45
|
const project = readProject()
|
|
50
|
-
const { srvPath, appPath, hasMta, hasHelm, hasHelmUnifiedRuntime, hasApprouter, apps } = project
|
|
46
|
+
const { isJava, srvPath, appPath, hasMta, hasMultitenancy, hasHelm, hasHelmUnifiedRuntime, hasApprouter, apps } = project
|
|
51
47
|
|
|
52
48
|
await Promise.all(apps.map(async ({app}) => {
|
|
53
49
|
project.app = app
|
|
54
50
|
await merge(__dirname, 'files/xs-app.json.hbs').into(join(appPath, app, 'xs-app.json'), { project })
|
|
55
51
|
}))
|
|
56
52
|
|
|
53
|
+
if (hasMultitenancy) {
|
|
54
|
+
await merge(__dirname, 'files/package.sidecar.json').into('mtx/sidecar/package.json')
|
|
55
|
+
}
|
|
56
|
+
|
|
57
57
|
if (hasMta) {
|
|
58
58
|
const srv = srv4(srvPath)
|
|
59
59
|
project.apps = apps
|
|
@@ -61,11 +61,8 @@ module.exports = class Html5RepoTemplate extends require('../../plugin') {
|
|
|
61
61
|
in: 'modules',
|
|
62
62
|
where: { type: 'html5', path: `${appPath}${app.app}` }
|
|
63
63
|
}))
|
|
64
|
-
const additions = [srv, appDeployer,
|
|
64
|
+
const additions = [srv, appDeployer, html5RepoHost, ...appModules]
|
|
65
65
|
const relationships = [{
|
|
66
|
-
insert: [destination, 'name'],
|
|
67
|
-
into: [appDeployer, 'requires', 'name'],
|
|
68
|
-
}, {
|
|
69
66
|
insert: [html5RepoHost, 'name'],
|
|
70
67
|
into: [appDeployer, 'requires', 'name'],
|
|
71
68
|
}]
|
|
@@ -76,6 +73,12 @@ module.exports = class Html5RepoTemplate extends require('../../plugin') {
|
|
|
76
73
|
into: [approuter, 'requires', 'name'],
|
|
77
74
|
})
|
|
78
75
|
}
|
|
76
|
+
if (hasMultitenancy) {
|
|
77
|
+
relationships.push({
|
|
78
|
+
insert: [html5Runtime, 'name'],
|
|
79
|
+
into: [mtxSidecar4(isJava ? 'mtx/sidecar' : 'gen/mtx/sidecar'), 'requires', 'name']
|
|
80
|
+
})
|
|
81
|
+
}
|
|
79
82
|
await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', { with: project,
|
|
80
83
|
additions,
|
|
81
84
|
relationships
|