@sap/cds-dk 9.4.2 → 9.5.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 +94 -0
- package/bin/compile/index.js +1 -1
- package/bin/data-products/index.js +10 -2
- package/bin/data-products/prepare-csn.js +63 -26
- package/bin/export.js +1 -1
- package/bin/help.js +2 -3
- package/bin/import.js +13 -3
- package/bin/repl.js +7 -11
- package/bin/up.js +164 -13
- package/bin/util/containerize.js +183 -0
- package/bin/version.js +4 -4
- package/lib/bind/k8s.js +1 -1
- package/lib/build/buildTaskEngine.js +5 -2
- package/lib/build/plugin.js +1 -1
- package/lib/build/plugins/helm/files/templates/_deployment_helpers.tpl +1 -1
- package/lib/build/plugins/helm/index.js +7 -7
- package/lib/build/provider/hana/2migration.js +16 -24
- package/lib/build/provider/hana/index.js +11 -3
- package/lib/build/provider/hana/template/.hdiconfig-all +7 -1
- package/lib/build/provider/hana/template/package.json +1 -1
- package/lib/build/provider/internalBuildPlugin.js +15 -1
- package/lib/build/provider/java/index.js +12 -1
- package/lib/build/provider/mtx-sidecar/index.js +2 -1
- package/lib/build/provider/nodejs/index.js +2 -1
- package/lib/build/util.js +3 -3
- package/lib/compile/to_openapi.js +1 -5
- package/lib/import/common.js +5 -4
- package/lib/import/message.js +1 -1
- package/lib/import/odata/ParserContext.js +1 -0
- package/lib/import/odata/v4parser.js +48 -3
- package/lib/import/openapi/importOpenAPI.js +6 -1
- package/lib/init/constants.js +1 -1
- package/lib/init/index.js +15 -6
- package/lib/init/merge.js +16 -0
- package/lib/init/projectReader.js +54 -24
- package/lib/init/registries/mta.js +5 -2
- package/lib/init/registries/xs-app.js +7 -1
- package/lib/init/template/ams/index.js +1 -1
- package/lib/init/template/app-frontend/files/app-package.json.hbs +1 -7
- package/lib/init/template/app-frontend/files/ui5.yaml.hbs +20 -1
- package/lib/init/template/app-frontend/index.js +0 -4
- package/lib/init/template/application-logging/index.js +9 -14
- package/lib/init/template/approuter/files/mta.yaml.hbs +7 -2
- package/lib/init/template/approuter/index.js +21 -16
- package/lib/init/template/audit-logging/index.js +2 -2
- package/lib/init/template/cloud-logging/index.js +2 -3
- package/lib/init/template/containerize/files/containerize.yaml.hbs +17 -3
- package/lib/init/template/containerize/index.js +0 -4
- package/lib/init/template/data/as-json.js +18 -20
- package/lib/init/template/destination/index.js +0 -4
- package/lib/init/template/dynatrace/index.js +0 -2
- package/lib/init/template/github-actions/files/kyma-setup/action.yaml +0 -2
- package/lib/init/template/github-actions/files/workflows/cf.yaml.hbs +16 -1
- package/lib/init/template/github-actions/files/workflows/test.yaml.hbs +20 -0
- package/lib/init/template/github-actions/index.js +5 -8
- package/lib/init/template/hana/files/db/package.json +2 -2
- package/lib/init/template/hana/files/mta.yaml.hbs +0 -4
- package/lib/init/template/hana/index.js +5 -7
- package/lib/init/template/helm/index.js +16 -33
- package/lib/init/template/helm-unified-runtime/index.js +0 -4
- package/lib/init/template/html5-repo/files/app-package.json.hbs +1 -7
- package/lib/init/template/html5-repo/files/containerize.yaml.hbs +0 -9
- package/lib/init/template/html5-repo/files/mta.yaml.hbs +0 -7
- package/lib/init/template/html5-repo/files/ui5.yaml.hbs +20 -1
- package/lib/init/template/html5-repo/files/values.yaml.hbs +6 -0
- package/lib/init/template/html5-repo/files/xs-app.json.hbs +5 -3
- package/lib/init/template/html5-repo/index.js +8 -14
- package/lib/init/template/ias/files/values.yaml.hbs +6 -6
- package/lib/init/template/ias/index.js +14 -23
- package/lib/init/template/kyma/index.js +14 -1
- package/lib/init/template/malware-scanner/files/mta.yaml.hbs +3 -1
- package/lib/init/template/malware-scanner/files/values.yaml +3 -1
- package/lib/init/template/multitenancy/files/mta.yaml.hbs +1 -3
- package/lib/init/template/multitenancy/files/values.yaml.hbs +8 -0
- package/lib/init/template/multitenancy/index.js +10 -5
- package/lib/init/template/nodejs/files/package.json.hbs +1 -1
- package/lib/init/template/pipeline/files/app-package.json.hbs +1 -7
- package/lib/init/template/pipeline/files/ui5.yaml.hbs +20 -1
- package/lib/init/template/pipeline/index.js +6 -3
- package/lib/init/template/portal/files/mta.yaml.hbs +5 -3
- package/lib/init/template/portal/index.js +3 -6
- package/lib/init/template/sample/files/_i18n/i18n_de.properties +12 -0
- package/lib/init/template/sample/files/_i18n/i18n_en.properties +21 -0
- package/lib/init/template/sample/files/_i18n/i18n_fr.properties +20 -0
- package/lib/init/template/sample/files/_i18n/messages_de.properties +34 -0
- package/lib/init/template/sample/files/_i18n/messages_en.properties +34 -0
- package/lib/init/template/sample/files/_i18n/messages_fr.properties +34 -0
- package/lib/init/template/sample/files/app/_i18n/i18n_de.properties +0 -26
- package/lib/init/template/sample/files/app/_i18n/i18n_en.properties +8 -0
- package/lib/init/template/sample/files/app/admin-authors/fiori-service.cds +52 -0
- package/lib/init/template/sample/files/app/admin-authors/webapp/Component.js.hbs +3 -0
- package/lib/init/template/sample/files/app/admin-authors/webapp/i18n/i18n.properties +11 -0
- package/lib/init/template/sample/files/app/admin-authors/webapp/manifest.json +130 -0
- package/lib/init/template/sample/files/app/admin-books/fiori-service.cds +81 -88
- package/lib/init/template/sample/files/app/admin-books/webapp/Component.js.hbs +3 -0
- package/lib/init/template/sample/files/app/admin-books/webapp/i18n/i18n.properties +10 -2
- package/lib/init/template/sample/files/app/admin-books/webapp/manifest.json +24 -48
- package/lib/init/template/sample/files/app/appconfig/fioriSandboxConfig.json +54 -3
- package/lib/init/template/sample/files/app/browse/fiori-service.cds +30 -30
- package/lib/init/template/sample/files/app/browse/webapp/Component.js.hbs +3 -0
- package/lib/init/template/sample/files/app/browse/webapp/i18n/i18n.properties +10 -3
- package/lib/init/template/sample/files/app/browse/webapp/manifest.json +18 -23
- package/lib/init/template/sample/files/app/common.cds +126 -158
- package/lib/init/template/sample/files/app/fiori-apps.html +30 -0
- package/lib/init/template/sample/files/app/genres/fiori-service.cds +33 -0
- package/lib/init/template/sample/files/app/genres/tree-view.cds +42 -0
- package/lib/init/template/sample/files/app/genres/value-help.cds +6 -0
- package/lib/init/template/sample/files/app/genres/webapp/Component.js.hbs +3 -0
- package/lib/init/template/sample/files/app/genres/webapp/i18n/i18n.properties +4 -0
- package/lib/init/template/sample/files/app/genres/webapp/i18n/i18n_de.properties +2 -0
- package/lib/init/template/sample/files/app/genres/webapp/manifest.json +126 -0
- package/lib/init/template/sample/files/app/services.cds +6 -2
- package/lib/init/template/sample/files/db/currencies.cds +13 -0
- package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Books.csv +5 -5
- package/lib/init/template/sample/files/db/data/{sap.capire.bookshop-Books_texts.csv → sap.capire.bookshop-Books.texts.csv} +4 -4
- package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Genres.csv +42 -15
- package/lib/init/template/sample/files/db/data/sap.common-Currencies.csv +12 -0
- package/lib/init/template/sample/files/db/data/sap.common-Currencies.texts.csv +15 -0
- package/lib/init/template/sample/files/db/hana/index.cds +10 -0
- package/lib/init/template/sample/files/db/schema.cds +35 -22
- package/lib/init/template/sample/files/db/sqlite/index.cds +10 -0
- package/lib/init/template/sample/files/package.json.hbs +14 -1
- package/lib/init/template/sample/files/srv/access-control.cds +3 -0
- package/lib/init/template/sample/files/srv/admin-service.cds +3 -2
- package/lib/init/template/sample/files/srv/cat-service.cds +7 -11
- package/lib/init/template/sample/index.js +26 -17
- package/lib/init/template/telemetry/index.js +1 -3
- package/lib/init/template/typescript/files/package.json +1 -1
- package/lib/init/template/workzone-standard/files/mta.yaml.hbs +0 -5
- package/lib/init/template/workzone-standard/index.js +0 -1
- package/lib/init/template/xsuaa/files/mta.yaml.hbs +4 -0
- package/lib/init/template/xsuaa/index.js +5 -7
- package/lib/lint/Linter.js +10 -4
- package/lib/lint/eslintHelp.json +1 -1
- package/lib/mtx/tenant_action.js +12 -4
- package/lib/util/checksum.js +32 -0
- package/lib/util/question.js +60 -7
- package/npm-shrinkwrap.json +61 -37
- package/package.json +2 -2
- package/lib/init/template/app-frontend/files/ui5-deploy.yaml.hbs +0 -25
- package/lib/init/template/github-actions/files/cf-setup/action.yaml +0 -53
- package/lib/init/template/html5-repo/files/ui5-deploy.yaml.hbs +0 -25
- package/lib/init/template/pipeline/files/ui5-deploy.yaml.hbs +0 -25
- package/lib/init/template/sample/files/app/_i18n/i18n.properties +0 -29
- package/lib/init/template/sample/files/app/admin-books/webapp/Component.js +0 -8
- package/lib/init/template/sample/files/app/admin-books/webapp/i18n/i18n_de.properties +0 -3
- package/lib/init/template/sample/files/app/admin-books/webapp/i18n/i18n_en.properties +0 -3
- package/lib/init/template/sample/files/app/browse/webapp/Component.js +0 -7
- package/lib/init/template/sample/files/app/browse/webapp/i18n/i18n_de.properties +0 -3
- package/lib/init/template/sample/files/app/browse/webapp/i18n/i18n_en.properties +0 -4
- package/lib/init/template/sample/files/app/index.html +0 -32
|
@@ -634,7 +634,7 @@ function _generateStructuredDataTypeCsn(dataType, propertyObject, isPrimaryKey,
|
|
|
634
634
|
|
|
635
635
|
function _parseAssociationProperty(foreignReference, associationNode, parserContext) {
|
|
636
636
|
const associationProperty = {};
|
|
637
|
-
associationProperty.type = (associationNode.$OnDelete === 'Cascade') ? 'cds.Composition' : 'cds.Association';
|
|
637
|
+
associationProperty.type = (associationNode.$OnDelete === 'Cascade' || associationNode.$ContainsTarget) ? 'cds.Composition' : 'cds.Association';
|
|
638
638
|
|
|
639
639
|
let schemaName = associationNode.$Type.substring(0, associationNode.$Type.lastIndexOf('.'));
|
|
640
640
|
|
|
@@ -642,6 +642,11 @@ function _parseAssociationProperty(foreignReference, associationNode, parserCont
|
|
|
642
642
|
schemaName = parserContext.schemaAliasToNamespace[schemaName];
|
|
643
643
|
}
|
|
644
644
|
|
|
645
|
+
if (associationNode.$ContainsTarget) {
|
|
646
|
+
parserContext.schemaDetails[schemaName] ??= {}
|
|
647
|
+
parserContext.schemaDetails[schemaName].containment = true
|
|
648
|
+
}
|
|
649
|
+
|
|
645
650
|
let resolvedEntityName;
|
|
646
651
|
let entityTypeMapping = (
|
|
647
652
|
parserContext.entityToEntitySetMap?.get(associationNode.$Type) ||
|
|
@@ -676,9 +681,18 @@ function _parseAssociationProperty(foreignReference, associationNode, parserCont
|
|
|
676
681
|
} else {
|
|
677
682
|
associationProperty.cardinality.max = 1;
|
|
678
683
|
}
|
|
679
|
-
|
|
684
|
+
|
|
685
|
+
// Generate on condition in case $Partner exists, as that indicates a backlink with which the
|
|
686
|
+
// condition can be generated.
|
|
687
|
+
// If not given convert managed associations and compositions in unmanaged with empty key to avoid
|
|
680
688
|
// "generation" of keys, that do not exist in the external service.
|
|
681
|
-
if (
|
|
689
|
+
if (associationNode.$Partner && associationProperty.type === 'cds.Composition') {
|
|
690
|
+
associationProperty.on = [
|
|
691
|
+
{ref: [foreignReference, associationNode.$Partner]},
|
|
692
|
+
'=',
|
|
693
|
+
{ref: ['$self']}
|
|
694
|
+
]
|
|
695
|
+
} else if (common.checkForEmptyKeys(associationProperty, "V4")) {
|
|
682
696
|
associationProperty.keys = [];
|
|
683
697
|
}
|
|
684
698
|
_captureAnnotationWithinElement(associationNode, associationProperty, parserContext);
|
|
@@ -1653,12 +1667,43 @@ function _generateCSN(edmxAsJson, ignorePersistenceSkip, parserContext, importer
|
|
|
1653
1667
|
csn.definitions[parserContext.primarySchema].kind = 'service';
|
|
1654
1668
|
csn.definitions[parserContext.primarySchema]['@cds.external'] = true;
|
|
1655
1669
|
|
|
1670
|
+
if (parserContext.schemaDetails[parserContext.primarySchema]?.containment) {
|
|
1671
|
+
csn.definitions[parserContext.primarySchema]['@odata.containment'] = true;
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1656
1674
|
// Step 8: parse entity container contents and their annotations
|
|
1657
1675
|
let schemaData = schemaDataList[parserContext.schemaToSchemaDataIndex[parserContext.primarySchema]];
|
|
1658
1676
|
let entityContainerElements = schemaData[parserContext.entityContainerName];
|
|
1659
1677
|
csn.definitions = Object.assign(_parseEntityContainer(csn.definitions, entityContainerElements, parserContext), csn.definitions);
|
|
1660
1678
|
}
|
|
1661
1679
|
|
|
1680
|
+
|
|
1681
|
+
// Step 9: 2. Step for generating $ContainsTarget & $Partner links
|
|
1682
|
+
// The containing composition is already generated. Now the Keys: [] has to be removed
|
|
1683
|
+
// on the backlink association because per OData spec, OData does not expose the foreign key fields
|
|
1684
|
+
// used by the backlink and thus it is save to assume they must be generated for proper mocking
|
|
1685
|
+
//
|
|
1686
|
+
// This happens after Step 8 because that adjusts the names of entity container entities where
|
|
1687
|
+
// entity type and entity set differ in naming
|
|
1688
|
+
for (const entity in csn.definitions) {
|
|
1689
|
+
if (entity.type !== 'entity') continue;
|
|
1690
|
+
|
|
1691
|
+
const containingCompositions = Object.keys(csn.definitions[entity].elements).filter(e =>
|
|
1692
|
+
csn.definitions[entity].elements[e].type === 'cds.Composition' &&
|
|
1693
|
+
csn.definitions[entity].elements[e].on
|
|
1694
|
+
);
|
|
1695
|
+
for (const comp of containingCompositions) {
|
|
1696
|
+
const compTarget = csn.definitions[csn.definitions[entity].elements[comp].target];
|
|
1697
|
+
const backLink = Object.keys(compTarget.elements).find(e =>
|
|
1698
|
+
compTarget.elements[e].type === 'cds.Association' &&
|
|
1699
|
+
compTarget.elements[e].target === entity
|
|
1700
|
+
)
|
|
1701
|
+
if (compTarget.elements[backLink].keys) {
|
|
1702
|
+
delete compTarget.elements[backLink].keys
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1662
1707
|
return JSON.stringify(csn, null, 4);
|
|
1663
1708
|
}
|
|
1664
1709
|
|
|
@@ -4,6 +4,8 @@ const {
|
|
|
4
4
|
pathAndMethod,
|
|
5
5
|
serviceName,
|
|
6
6
|
} = require("./utilities");
|
|
7
|
+
const cds = require('../../cds');
|
|
8
|
+
|
|
7
9
|
|
|
8
10
|
module.exports = { importOpenAPI };
|
|
9
11
|
|
|
@@ -32,7 +34,10 @@ function importOpenAPI(input) {
|
|
|
32
34
|
};
|
|
33
35
|
|
|
34
36
|
const context = {
|
|
35
|
-
serviceName: serviceName(
|
|
37
|
+
serviceName: serviceName(cds.cli.options["into-namespace"]
|
|
38
|
+
?? input.info?.title
|
|
39
|
+
?? "TODO.service"
|
|
40
|
+
),
|
|
36
41
|
oasVersion: input.openapi || input.swagger,
|
|
37
42
|
v3: !!input.openapi,
|
|
38
43
|
schemas: input.openapi ? input.components?.schemas : input.definitions,
|
package/lib/init/constants.js
CHANGED
package/lib/init/index.js
CHANGED
|
@@ -231,17 +231,26 @@ module.exports = class CDSGenerator {
|
|
|
231
231
|
const templates = new Map
|
|
232
232
|
for (let plugin of plugins) {
|
|
233
233
|
// Compat
|
|
234
|
-
if (plugin === 'appfront') plugin = 'app-front'
|
|
235
234
|
if (plugin === 'helm' && cds.cli.options['internal-unified-runtime-charts']) {
|
|
235
|
+
console.warn(term.warn('"--internal-unified-runtime-charts" is deprecated, please use "cds add kyma --unified-runtime" instead'))
|
|
236
236
|
plugin = 'helm-unified-runtime'
|
|
237
237
|
cds.cli.options.add?.delete('helm')
|
|
238
238
|
cds.cli.options.add?.add('helm-unified-runtime')
|
|
239
239
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
240
|
+
const _alias = (alias, preferred) => {
|
|
241
|
+
if (plugin === alias) {
|
|
242
|
+
plugin = preferred
|
|
243
|
+
cds.cli.options.add?.delete(alias)
|
|
244
|
+
cds.cli.options.add?.add(preferred)
|
|
245
|
+
cds.cli.argv[0] = cds.cli.argv[0].replace(alias, preferred)
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
_alias('appfront', 'app-frontend')
|
|
249
|
+
_alias('app-front', 'app-frontend')
|
|
250
|
+
_alias('gha', 'github-actions')
|
|
251
|
+
_alias('postgresql', 'postgres')
|
|
252
|
+
_alias('kibana', 'application-logging')
|
|
253
|
+
_alias('kibana-logging', 'application-logging')
|
|
245
254
|
|
|
246
255
|
if (!templates.has(plugin)) {
|
|
247
256
|
const template = await this._createTemplate(plugin)
|
package/lib/init/merge.js
CHANGED
|
@@ -106,6 +106,9 @@ async function _mergeYAML(into, from, project, semantics = {}) {
|
|
|
106
106
|
if (project) await writeYAML(into, source)
|
|
107
107
|
else await copy(from, into)
|
|
108
108
|
return source
|
|
109
|
+
} else if (typeof into === 'string') {
|
|
110
|
+
await writeYAML(into, source)
|
|
111
|
+
return source
|
|
109
112
|
}
|
|
110
113
|
throw new Error(`Target YAML doesn't exist`)
|
|
111
114
|
}
|
|
@@ -113,6 +116,19 @@ async function _mergeYAML(into, from, project, semantics = {}) {
|
|
|
113
116
|
const entryMap = new Map, templateEntryMap = new Map
|
|
114
117
|
|
|
115
118
|
const { additions, overwrites, deletions, relationships } = semantics
|
|
119
|
+
if (relationships && Array.isArray(relationships)) {
|
|
120
|
+
semantics.additions ??= []
|
|
121
|
+
const add = semantics.additions
|
|
122
|
+
|
|
123
|
+
for (const rel of relationships) {
|
|
124
|
+
for (const ins of (Array.isArray(rel.insert) ? rel.insert : [rel.insert])) {
|
|
125
|
+
if (!add.includes(ins)) add.push(ins)
|
|
126
|
+
}
|
|
127
|
+
const base = rel.into?.[0]
|
|
128
|
+
if (base && !add.includes(base)) add.push(base)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
116
132
|
for (const entry of additions ?? []) {
|
|
117
133
|
entryMap.set(entry, undefined)
|
|
118
134
|
templateEntryMap.set(entry, undefined)
|
|
@@ -15,7 +15,7 @@ module.exports = new class ProjectReader {
|
|
|
15
15
|
|
|
16
16
|
#setPackageInfo() {
|
|
17
17
|
this.isJava = (exists('pom.xml') || cds.cli.options?.add?.has('java'))
|
|
18
|
-
|
|
18
|
+
&& !cds.env.for('cds').profiles.includes('node') // opt-out for hybrid projects like sflight
|
|
19
19
|
|
|
20
20
|
// 1. Use project name and static default values
|
|
21
21
|
this.appVersion = this.isJava ? '1.0.0-SNAPSHOT' : '1.0.0'
|
|
@@ -32,7 +32,7 @@ module.exports = new class ProjectReader {
|
|
|
32
32
|
const v = version?.[0] === '${revision}' ? properties?.[0]?.revision[0] : version?.[0] ?? '1.0.0-SNAPSHOT'
|
|
33
33
|
if (v && REGEX_JAVA_VERSION.test(v)) this.appVersion = v
|
|
34
34
|
this.jdkVersion = properties?.[0]?.['jdk.version']?.[0]?._text?.[0] ?? JAVA_LTS_VERSIONS[JAVA_LTS_VERSIONS.length - 1]
|
|
35
|
-
if (artifactId?.[0])
|
|
35
|
+
if (artifactId?.[0]) this.appName = this.appId = artifactId?.[0]?.split(/-parent/)[0]
|
|
36
36
|
if (description?.[0]) this.appDescription = description[0]
|
|
37
37
|
}
|
|
38
38
|
else if (exists('package.json')) {
|
|
@@ -73,9 +73,9 @@ module.exports = new class ProjectReader {
|
|
|
73
73
|
TRACE?.({ env })
|
|
74
74
|
|
|
75
75
|
const pkgJson = () => exists('package.json') ? JSON.parse(fs.readFileSync(join(cds.root, 'package.json'))) : {}
|
|
76
|
-
const _isESM
|
|
76
|
+
const _isESM = () => pkgJson().type === 'module'
|
|
77
77
|
const _isTypescript = () => !!pkgJson().dependencies?.typescript || !!pkgJson().devDependencies?.typescript
|
|
78
|
-
const _hasTyper
|
|
78
|
+
const _hasTyper = () => !!pkgJson().dependencies?.['@cap-js/cds-typer'] || !!pkgJson().devDependencies?.['@cap-js/cds-typer']
|
|
79
79
|
const _inProd = plugin => require(`./template/${plugin}`).hasInProduction(env) || cds.cli.argv[0]?.includes(plugin) || cds.cli.options.add?.has(plugin)
|
|
80
80
|
const _uiEmbedded = () => exists(join(env.folders.app, 'xs-app.json'))
|
|
81
81
|
const _uiModule = () => !_uiEmbedded() && isdir(env.folders.app) && fs.readdirSync(resolve(cds.root, env.folders.app)).length > 0
|
|
@@ -121,9 +121,22 @@ module.exports = new class ProjectReader {
|
|
|
121
121
|
const manifestPath = path.resolve(cds.root, cds.env.folders.app, app, 'webapp/manifest.json')
|
|
122
122
|
const manifest = exists(manifestPath) ? JSON.parse(fs.readFileSync(manifestPath, 'utf-8')) : {}
|
|
123
123
|
const inbounds = manifest?.['sap.app']?.crossNavigation?.inbounds
|
|
124
|
-
const [firstInbound] = Object.values(inbounds ?? { intent: { semanticObject: 'Books', action: 'display' }})
|
|
124
|
+
const [firstInbound] = Object.values(inbounds ?? { intent: { semanticObject: 'Books', action: 'display' } })
|
|
125
125
|
const vizId = firstInbound.semanticObject + '-' + firstInbound.action
|
|
126
|
-
|
|
126
|
+
// Try to read archiveName from ui5.yaml if it exists
|
|
127
|
+
let archiveName = ''
|
|
128
|
+
const ui5DeployPath = path.resolve(cds.root, cds.env.folders.app, app, 'ui5.yaml')
|
|
129
|
+
if (exists(ui5DeployPath)) {
|
|
130
|
+
const ui5Deploy = cds.load.yaml(ui5DeployPath)
|
|
131
|
+
const customTasks = ui5Deploy?.builder?.customTasks
|
|
132
|
+
if (Array.isArray(customTasks)) {
|
|
133
|
+
const zipperTask = customTasks.find(t => t.name === 'ui5-task-zipper')
|
|
134
|
+
if (zipperTask?.configuration?.archiveName) {
|
|
135
|
+
archiveName = `${zipperTask.configuration.archiveName}.zip`
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return { app, strippedApp: app.replace(/-/g, ''), vizId, isNotLast: i < apps.length - 1, manifestAppId: manifest?.['sap.app']?.id ?? app, archiveName }
|
|
127
140
|
})
|
|
128
141
|
},
|
|
129
142
|
appUIPaths: () => {
|
|
@@ -133,7 +146,7 @@ module.exports = new class ProjectReader {
|
|
|
133
146
|
isdir(path.join(cds.root, cds.env.folders.app, e)) && isApp(e)
|
|
134
147
|
)
|
|
135
148
|
},
|
|
136
|
-
hasIndexHtml: () => {},
|
|
149
|
+
hasIndexHtml: () => { },
|
|
137
150
|
appPath: () => env.folders.app,
|
|
138
151
|
appVersion: () => appVersion,
|
|
139
152
|
jdkVersion: () => jdkVersion,
|
|
@@ -146,12 +159,14 @@ module.exports = new class ProjectReader {
|
|
|
146
159
|
hasUIEmbedded: _uiEmbedded,
|
|
147
160
|
hasUIModule: _uiModule,
|
|
148
161
|
hasUI: () => _uiEmbedded() || _uiModule(),
|
|
162
|
+
hasUI5: () => _uiEmbedded() || _uiModule(),
|
|
149
163
|
literal: () => () => text => text,
|
|
150
164
|
hasMTXRoute: () => _inProd('extensibility') || (_inProd('multitenancy') && !_isJava()),
|
|
151
165
|
hasMTXRouteJava: () => (_inProd('helm-unified-runtime') || _inProd('helm')) && _isJava() && _inProd('multitenancy'),
|
|
152
166
|
sap: () => cds.cli.options.sap,
|
|
153
167
|
imageRegistry: () => exists('chart/values.yaml') ? cds.load.yaml(join(cds.root, 'chart/values.yaml')).global?.image?.registry ?? '<your-container-registry-server>' : '<your-container-registry-server>',
|
|
154
168
|
extendsApp: _extends,
|
|
169
|
+
isBas: () => Object.entries(process.env).some(([key, value]) => key === 'WS_BASE_URL' && value.includes('applicationstudio') || /THEIA_(DEFAULT_)?PLUGINS/.test(key)),
|
|
155
170
|
npmWorkspaceRoot: () => {
|
|
156
171
|
if (this.cachedWorkspaceRoot) return this.cachedWorkspaceRoot
|
|
157
172
|
this.cachedWorkspaceRoot = execSync('npm prefix', { encoding: 'utf8', cwd: cds.root, stdio: 'pipe' }).trim()
|
|
@@ -160,8 +175,22 @@ module.exports = new class ProjectReader {
|
|
|
160
175
|
isMonorepoMicroservice: function () {
|
|
161
176
|
return this.npmWorkspaceRoot() !== cds.root
|
|
162
177
|
},
|
|
163
|
-
hasRoles: () => {}, roles: () => {}, // for xs-security generation
|
|
164
|
-
hasCustomRoleCollections: () => exists('xs-security.json') && !!JSON.parse(fs.readFileSync(path.join(cds.root, 'xs-security.json')))['role-collections']
|
|
178
|
+
hasRoles: () => { }, roles: () => { }, // for xs-security generation
|
|
179
|
+
hasCustomRoleCollections: () => exists('xs-security.json') && !!JSON.parse(fs.readFileSync(path.join(cds.root, 'xs-security.json')))['role-collections'],
|
|
180
|
+
k8s: () => {
|
|
181
|
+
if (!exists('chart/values.yaml')) return {}
|
|
182
|
+
|
|
183
|
+
const values = cds.load.yaml(join(cds.root, 'chart/values.yaml'))
|
|
184
|
+
|
|
185
|
+
let containerize = {}
|
|
186
|
+
if (exists('containerize.yaml'))
|
|
187
|
+
containerize = cds.load.yaml(join(cds.root, 'containerize.yaml'))
|
|
188
|
+
|
|
189
|
+
return {
|
|
190
|
+
values: values ?? {},
|
|
191
|
+
containerize: containerize ?? {}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
165
194
|
}
|
|
166
195
|
|
|
167
196
|
// Automatically creates availability checks for `cds add` commands.
|
|
@@ -169,7 +198,8 @@ module.exports = new class ProjectReader {
|
|
|
169
198
|
// E.g. `cds add hana` can be checked using `hasHana` or `isHana`
|
|
170
199
|
const project = (() => {
|
|
171
200
|
const defined = {}
|
|
172
|
-
const _get = property => {
|
|
201
|
+
const _get = property => {
|
|
202
|
+
const p = property
|
|
173
203
|
if (p in reserved) return reserved[p]()
|
|
174
204
|
for (const prefix of ['has', 'is', 'add']) if (p.startsWith(prefix) && p.length > prefix.length) {
|
|
175
205
|
const facet = p.slice(prefix.length).replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase()
|
|
@@ -200,23 +230,23 @@ module.exports = new class ProjectReader {
|
|
|
200
230
|
* @param {string[]?} roots array of directories to search for application.yaml, like `srv`
|
|
201
231
|
* @returns {Promise<object[]>} array of objects with `cds` property
|
|
202
232
|
*/
|
|
203
|
-
module.exports._readSpringBootConfig = async function (roots=[cds.env.folders.srv]) {
|
|
233
|
+
module.exports._readSpringBootConfig = async function (roots = [cds.env.folders.srv]) {
|
|
204
234
|
const configNodes = []
|
|
205
235
|
const rootDirs = roots.map(d => join(cds.root, d))
|
|
206
236
|
for (let r of rootDirs) {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
237
|
+
const file = isfile(join(r, './src/main/resources/application.yaml'))
|
|
238
|
+
if (file) {
|
|
239
|
+
const yaml = cds.load.yaml(file)
|
|
240
|
+
for (let yamlDoc of Array.isArray(yaml) ? yaml : [yaml]) {
|
|
241
|
+
let cds = yamlDoc?.cds;
|
|
242
|
+
if (!cds) continue
|
|
243
|
+
cds = _normalizeSpringBootCfg(cds)
|
|
244
|
+
configNodes.push({ cds })
|
|
245
|
+
}
|
|
215
246
|
}
|
|
216
|
-
}
|
|
217
247
|
}
|
|
218
248
|
return configNodes
|
|
219
|
-
|
|
249
|
+
}
|
|
220
250
|
|
|
221
251
|
/**
|
|
222
252
|
* Normalize SpringBoot's dots in keys to express nested objects
|
|
@@ -226,7 +256,7 @@ module.exports._readSpringBootConfig = async function (roots=[cds.env.folders.sr
|
|
|
226
256
|
* @returns {object}
|
|
227
257
|
*/
|
|
228
258
|
function _normalizeSpringBootCfg(obj) {
|
|
229
|
-
if (typeof obj !== 'object')
|
|
259
|
+
if (typeof obj !== 'object') return obj
|
|
230
260
|
Object.keys(obj).forEach(k => {
|
|
231
261
|
const prop = k.split('.')
|
|
232
262
|
const last = prop.pop()
|
|
@@ -239,7 +269,7 @@ function _normalizeSpringBootCfg(obj) {
|
|
|
239
269
|
// recursively normalize
|
|
240
270
|
_normalizeSpringBootCfg(obj[k])
|
|
241
271
|
// delete the original property from object if it was rewritten
|
|
242
|
-
if (prop.length)
|
|
272
|
+
if (prop.length) delete obj[k]
|
|
243
273
|
})
|
|
244
274
|
return obj
|
|
245
275
|
}
|
|
@@ -296,4 +326,4 @@ function _normalizeSpringBootCfg(obj) {
|
|
|
296
326
|
* @property {String} githubSlug GitHub org/repo.
|
|
297
327
|
* @property {boolean} isMonorepoMicroservice Indicates if the project is a monorepo microservice.
|
|
298
328
|
* @property {String} npmWorkspaceRoot The root path of the monorepo workspace.
|
|
299
|
-
*/
|
|
329
|
+
*/
|
|
@@ -15,6 +15,8 @@ const appFront = {
|
|
|
15
15
|
where: { type: 'org.cloudfoundry.managed-service', 'parameters.service': 'app-front' }
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
const ias = { in: 'resources', where: { 'parameters.service': 'identity' } }
|
|
19
|
+
|
|
18
20
|
const xsuaa = {
|
|
19
21
|
in: 'resources',
|
|
20
22
|
where: { type: 'org.cloudfoundry.managed-service', 'parameters.service': 'xsuaa', 'parameters.service-plan': 'application' }
|
|
@@ -150,9 +152,9 @@ const requiredAppApi4 = module => ({
|
|
|
150
152
|
where: { name: 'app-api' }
|
|
151
153
|
})
|
|
152
154
|
|
|
153
|
-
const requiredMtxSidecarApi4 = srv => ({
|
|
155
|
+
const requiredMtxSidecarApi4 = (srv, name) => ({
|
|
154
156
|
in: [srv, 'requires'],
|
|
155
|
-
where: { 'properties.CDS_MULTITENANCY_SIDECAR_URL':
|
|
157
|
+
where: { 'properties.CDS_MULTITENANCY_SIDECAR_URL': name }
|
|
156
158
|
})
|
|
157
159
|
|
|
158
160
|
const requiredJavaApprouterApi4 = srv => ({
|
|
@@ -208,6 +210,7 @@ const auditlog = {
|
|
|
208
210
|
module.exports = {
|
|
209
211
|
srv4,
|
|
210
212
|
approuter,
|
|
213
|
+
ias,
|
|
211
214
|
xsuaa,
|
|
212
215
|
xsuaa4,
|
|
213
216
|
destination,
|
|
@@ -15,7 +15,7 @@ module.exports = class AmsTemplate extends require('../../plugin') {
|
|
|
15
15
|
|
|
16
16
|
static hasInProduction(env) {
|
|
17
17
|
const { dependencies, devDependencies } = readProject()
|
|
18
|
-
return env.requires?.auth?.ams || devDependencies?.['@sap/ams-dev'] || dependencies?.['@sap/ams']
|
|
18
|
+
return env.requires?.auth?.ams || devDependencies?.['@sap/ams-dev'] || devDependencies?.['@sap/ams'] || dependencies?.['@sap/ams']
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
async run() {
|
|
@@ -3,18 +3,12 @@
|
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"main": "webapp/index.html",
|
|
5
5
|
"scripts": {
|
|
6
|
-
"build": "ui5 build preload --clean-dest
|
|
7
|
-
"build-local": "ui5 build preload --clean-dest",
|
|
6
|
+
"build": "ui5 build preload --clean-dest",
|
|
8
7
|
"start": "ui5 serve"
|
|
9
8
|
},
|
|
10
9
|
"devDependencies": {
|
|
11
10
|
"@ui5/cli": "^4",
|
|
12
11
|
"ui5-task-zipper": "^3"
|
|
13
|
-
},
|
|
14
|
-
"ui5": {
|
|
15
|
-
"dependencies": [
|
|
16
|
-
"ui5-task-zipper"
|
|
17
|
-
]
|
|
18
12
|
}
|
|
19
13
|
{{/hasUI5}}
|
|
20
14
|
}
|
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
---
|
|
2
2
|
# yaml-language-server: $schema=https://sap.github.io/ui5-tooling/schema/ui5.yaml.json
|
|
3
|
-
specVersion: '
|
|
3
|
+
specVersion: '4.0'
|
|
4
4
|
metadata:
|
|
5
5
|
name: {{app}}
|
|
6
6
|
type: application
|
|
7
|
+
resources:
|
|
8
|
+
configuration:
|
|
9
|
+
propertiesFileSourceEncoding: UTF-8
|
|
10
|
+
builder:
|
|
11
|
+
resources:
|
|
12
|
+
excludes:
|
|
13
|
+
- "/test/**"
|
|
14
|
+
- "/localService/**"
|
|
15
|
+
customTasks:
|
|
16
|
+
- name: ui5-task-zipper
|
|
17
|
+
afterTask: generateVersionInfo
|
|
18
|
+
configuration:
|
|
19
|
+
archiveName: {{app}}
|
|
20
|
+
additionalFiles:
|
|
21
|
+
- xs-app.json
|
|
22
|
+
{{#isTypescript}}
|
|
23
|
+
- name: ui5-tooling-transpile-task
|
|
24
|
+
afterTask: replaceVersion
|
|
25
|
+
{{/isTypescript}}
|
|
@@ -26,10 +26,6 @@ module.exports = class extends require('../../plugin') {
|
|
|
26
26
|
project.app = app
|
|
27
27
|
await merge(__dirname, 'files/ui5.yaml.hbs').into(join(appPath, app, 'ui5.yaml'), { project })
|
|
28
28
|
}
|
|
29
|
-
for (const { app } of apps) {
|
|
30
|
-
project.app = app
|
|
31
|
-
await merge(__dirname, 'files/ui5-deploy.yaml.hbs').into(join(appPath, app, 'ui5-deploy.yaml'), { project })
|
|
32
|
-
}
|
|
33
29
|
}
|
|
34
30
|
|
|
35
31
|
for (const { app } of apps) {
|
|
@@ -28,28 +28,23 @@ module.exports = class ApplicationLoggingTemplate extends require('../../plugin'
|
|
|
28
28
|
|
|
29
29
|
async combine() {
|
|
30
30
|
const project = readProject()
|
|
31
|
-
const { addMta,
|
|
31
|
+
const { addMta, hasMta, hasApprouter, isJava, addMultitenancy, hasMultitenancy, srvPath } = project
|
|
32
32
|
|
|
33
|
-
if (addMta || addMultitenancy) {
|
|
33
|
+
if (addMta || (addMultitenancy && hasMta)) {
|
|
34
34
|
const additions = [], relationships = []
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
})
|
|
42
|
-
}
|
|
43
|
-
if (addMultitenancy) {
|
|
35
|
+
const srv = srv4(srvPath)
|
|
36
|
+
relationships.push({
|
|
37
|
+
insert: [applicationLogging, 'name'],
|
|
38
|
+
into: [srv, 'requires', 'name']
|
|
39
|
+
})
|
|
40
|
+
if (hasMultitenancy) {
|
|
44
41
|
const mtxSidecar = mtxSidecar4(isJava ? 'mtx/sidecar' : 'gen/mtx/sidecar')
|
|
45
|
-
additions.push(mtxSidecar)
|
|
46
42
|
relationships.push({
|
|
47
43
|
insert: [applicationLogging, 'name'],
|
|
48
44
|
into: [mtxSidecar, 'requires', 'name']
|
|
49
45
|
})
|
|
50
46
|
}
|
|
51
|
-
if (
|
|
52
|
-
additions.push(approuter)
|
|
47
|
+
if (hasApprouter) {
|
|
53
48
|
relationships.push({
|
|
54
49
|
insert: [applicationLogging, 'name'],
|
|
55
50
|
into: [approuter, 'requires', 'name']
|
|
@@ -57,7 +57,6 @@ modules:
|
|
|
57
57
|
url: ${default-url}
|
|
58
58
|
{{/isJava}}
|
|
59
59
|
|
|
60
|
-
{{#hasMultitenancy}}
|
|
61
60
|
- name: {{appName}}-mtx
|
|
62
61
|
type: nodejs
|
|
63
62
|
path: {{#isNodejs}}gen/{{/isNodejs}}mtx/sidecar{{#isNodejs}}
|
|
@@ -66,7 +65,6 @@ modules:
|
|
|
66
65
|
properties:
|
|
67
66
|
SUBSCRIPTION_URL: ~{app-protocol}://\${tenant_subdomain}-~{app-uri}
|
|
68
67
|
{{/isNodejs}}
|
|
69
|
-
{{/hasMultitenancy}}
|
|
70
68
|
|
|
71
69
|
resources:
|
|
72
70
|
- name: {{appName}}-auth
|
|
@@ -83,3 +81,10 @@ resources:
|
|
|
83
81
|
oauth2-configuration:
|
|
84
82
|
redirect-uris:
|
|
85
83
|
- https://*~{app-api/app-uri}/**
|
|
84
|
+
|
|
85
|
+
- name: {{appName}}-ias
|
|
86
|
+
type: org.cloudfoundry.managed-service
|
|
87
|
+
requires:
|
|
88
|
+
- name: app-api
|
|
89
|
+
parameters:
|
|
90
|
+
service: identity
|
|
@@ -5,7 +5,7 @@ const { readProject } = require('../../projectReader')
|
|
|
5
5
|
const { sort, merge } = require('../../merge')
|
|
6
6
|
const {
|
|
7
7
|
srv4, mtxSidecar4, approuter, // Modules
|
|
8
|
-
xsuaa, // BTP Services
|
|
8
|
+
xsuaa, ias, // BTP Services
|
|
9
9
|
requiredMtxApi, requiredJavaApprouterApi4, providedJavaApprouterApi, // APIs
|
|
10
10
|
requiredAppApi4, providedAppApi,
|
|
11
11
|
approuterMTXRoute,
|
|
@@ -34,30 +34,35 @@ module.exports = class ApprouterTemplate extends require('../../plugin') {
|
|
|
34
34
|
const project = readProject()
|
|
35
35
|
const {
|
|
36
36
|
isNodejs, isJava,
|
|
37
|
-
addXsuaa, hasXsuaa, addMultitenancy, hasMTXRoute, hasMTXRouteJava,
|
|
38
|
-
addMta, addHelm, addHelmUnifiedRuntime,
|
|
37
|
+
addIas, addXsuaa, hasXsuaa, hasIas, addMultitenancy, hasMTXRoute, hasMTXRouteJava,
|
|
38
|
+
addMta, addHelm, addHelmUnifiedRuntime,
|
|
39
|
+
hasMta, hasHelm, hasHelmUnifiedRuntime, hasMultitenancy,
|
|
39
40
|
addContainerize, srvPath, approuterPath
|
|
40
41
|
} = project
|
|
41
42
|
|
|
42
43
|
|
|
43
|
-
if (addMta || (addMultitenancy || addXsuaa) && hasMta) {
|
|
44
|
+
if (addMta || (addMultitenancy || addXsuaa || addIas) && hasMta) {
|
|
44
45
|
const srv = srv4(srvPath)
|
|
45
|
-
const apis = isJava &&
|
|
46
|
+
const apis = isJava && hasMultitenancy ? [requiredJavaApprouterApi4(srv), providedJavaApprouterApi] : []
|
|
46
47
|
const mtxSidecar = mtxSidecar4(isJava ? 'mtx/sidecar' : 'gen/mtx/sidecar')
|
|
47
|
-
if (isNodejs &&
|
|
48
|
-
if (isJava &&
|
|
48
|
+
if (isNodejs && hasMultitenancy) apis.push(requiredMtxApi, requiredAppApi4(mtxSidecar), providedAppApi)
|
|
49
|
+
if (isJava && hasMultitenancy) apis.push(requiredMtxApi)
|
|
49
50
|
const modules = [srv, approuter]
|
|
50
|
-
if (
|
|
51
|
+
if (hasMultitenancy) modules.push(mtxSidecar)
|
|
51
52
|
const additions = [...modules, ...apis]
|
|
52
|
-
if (hasXsuaa) additions.push(xsuaa)
|
|
53
53
|
const relationships = []
|
|
54
|
-
if (hasXsuaa)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
54
|
+
if (hasXsuaa) {
|
|
55
|
+
relationships.push({
|
|
56
|
+
insert: [xsuaa, 'name'],
|
|
57
|
+
into: [approuter, 'requires', 'name']
|
|
58
|
+
})
|
|
59
|
+
}
|
|
60
|
+
if (hasIas) {
|
|
61
|
+
relationships.push({
|
|
62
|
+
insert: [ias, 'name'],
|
|
63
|
+
into: [approuter, 'requires', 'name']
|
|
64
|
+
})
|
|
65
|
+
}
|
|
61
66
|
await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', {
|
|
62
67
|
with: project, additions, relationships,
|
|
63
68
|
})
|
|
@@ -33,7 +33,7 @@ module.exports = class AuditLoggingTemplate extends require('../../plugin') {
|
|
|
33
33
|
|
|
34
34
|
async combine() {
|
|
35
35
|
const project = readProject()
|
|
36
|
-
const { addMta, addHelm, addMultitenancy, srvPath } = project
|
|
36
|
+
const { addMta, addHelm, addHelmUnifiedRuntime, addMultitenancy, srvPath } = project
|
|
37
37
|
const { plan = 'premium' } = cds.cli.options
|
|
38
38
|
project.servicePlan = plan
|
|
39
39
|
|
|
@@ -53,7 +53,7 @@ module.exports = class AuditLoggingTemplate extends require('../../plugin') {
|
|
|
53
53
|
]
|
|
54
54
|
})
|
|
55
55
|
}
|
|
56
|
-
if (addHelm) {
|
|
56
|
+
if (addHelm || addHelmUnifiedRuntime) {
|
|
57
57
|
await merge({
|
|
58
58
|
srv: { bindings: { auditlog: { serviceInstanceName: 'auditlog' }}},
|
|
59
59
|
auditlog: {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const cds = require('../../../cds')
|
|
2
2
|
const { merge, sort } = require('../../merge')
|
|
3
3
|
|
|
4
|
+
const mvn = require('../../mvn')
|
|
4
5
|
const { readProject } = require('../../projectReader')
|
|
5
6
|
const { srv4, mtxSidecar4, approuter } = require('../../registries/mta')
|
|
6
7
|
|
|
@@ -32,6 +33,7 @@ module.exports = class extends require('../../plugin') {
|
|
|
32
33
|
await sort('package.json', 'dependencies')
|
|
33
34
|
} else if (isJava) {
|
|
34
35
|
await merge(__dirname, 'files/java-cdsrc.json.hbs').into('.cdsrc.json', { with: project })
|
|
36
|
+
await mvn.add('APPLICATION_LOGGING')
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
39
|
|
|
@@ -50,7 +52,6 @@ module.exports = class extends require('../../plugin') {
|
|
|
50
52
|
const additions = [cloudLogging], relationships = []
|
|
51
53
|
const srv = srv4(srvPath)
|
|
52
54
|
if (addMta) {
|
|
53
|
-
additions.push(srv)
|
|
54
55
|
relationships.push({
|
|
55
56
|
insert: [cloudLogging, 'name'],
|
|
56
57
|
into: [srv, 'requires', 'name']
|
|
@@ -58,14 +59,12 @@ module.exports = class extends require('../../plugin') {
|
|
|
58
59
|
}
|
|
59
60
|
if (addMultitenancy) {
|
|
60
61
|
const mtxSidecar = mtxSidecar4(isJava ? 'mtx/sidecar' : 'gen/mtx/sidecar')
|
|
61
|
-
additions.push(mtxSidecar)
|
|
62
62
|
relationships.push({
|
|
63
63
|
insert: [cloudLogging, 'name'],
|
|
64
64
|
into: [mtxSidecar, 'requires', 'name']
|
|
65
65
|
})
|
|
66
66
|
}
|
|
67
67
|
if (addApprouter) {
|
|
68
|
-
additions.push(approuter)
|
|
69
68
|
relationships.push({
|
|
70
69
|
insert: [cloudLogging, 'name'],
|
|
71
70
|
into: [approuter, 'requires', 'name']
|