@sap/cds-dk 8.9.4 → 9.0.4
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 +89 -2012
- package/LICENSE +15 -21
- package/bin/bind.js +1 -1
- package/bin/build.js +35 -37
- package/bin/cds.js +12 -29
- package/bin/compile/index.js +2 -2
- package/bin/debug.js +27 -7
- package/bin/deploy/index.js +6 -23
- package/bin/deploy/to-hana.js +4 -2
- package/bin/help.js +3 -1
- package/bin/init.js +1 -1
- package/bin/up.js +45 -12
- package/bin/watch.js +45 -63
- package/lib/bind/cf.js +2 -1
- package/lib/bind/k8s.js +2 -2
- package/lib/bind/plugin.js +1 -1
- package/lib/bind/shared.js +16 -25
- package/lib/build/buildTaskEngine.js +26 -10
- package/lib/build/buildTaskFactory.js +3 -2
- package/lib/build/buildTaskProvider.js +18 -7
- package/lib/build/buildTaskProviderFactory.js +35 -13
- package/lib/build/constants.js +4 -0
- package/lib/build/index.js +1 -1
- package/lib/build/plugin.js +89 -54
- package/lib/build/plugins/helm/files/subcharts/web-application/Chart.yaml +3 -1
- package/lib/build/plugins/helm/files/subcharts/web-application/templates/_helpers.tpl +4 -2
- package/lib/build/plugins/helm/files/subcharts/web-application/templates/api-rule.yaml +4 -2
- package/lib/build/plugins/helm/files/subcharts/web-application/templates/deployment.yaml +18 -1
- package/lib/build/plugins/helm/files/subcharts/web-application/templates/service-binding.yaml +0 -1
- package/lib/build/plugins/helm/files/subcharts/web-application/values.schema.json +34 -2
- package/lib/build/plugins/helm/files/subcharts/web-application/values.yaml +9 -2
- package/lib/build/plugins/helm/index.js +2 -1
- package/lib/build/plugins.js +24 -10
- package/lib/build/provider/edmxBuildPlugin.js +1 -11
- package/lib/build/provider/hana/index.js +12 -5
- package/lib/build/provider/hana/template/package.json +1 -1
- package/lib/build/provider/internalBuildPlugin.js +1 -1
- package/lib/build/provider/internalBuildTaskProvider.js +3 -24
- package/lib/build/provider/java/index.js +1 -1
- package/lib/build/provider/mtx-extension/index.js +3 -8
- package/lib/build/provider/nodejs/index.js +28 -6
- package/lib/build/util.js +186 -125
- package/lib/deploy/index.js +5 -0
- package/lib/deploy/to-hana/hana.js +27 -33
- package/lib/deploy/to-hana/hdiDeployUtil.js +2 -2
- package/lib/import/odata/v2parser.js +34 -3
- package/lib/import/openapi/importOpenAPI.js +4 -0
- package/lib/index.js +2 -11
- package/lib/init/constants.js +0 -1
- package/lib/init/merge.js +101 -77
- package/lib/init/mvn.js +3 -3
- package/lib/init/projectReader.js +1 -1
- package/lib/init/template/ams/files/mta.yaml.hbs +6 -1
- package/lib/init/template/ams/files/package.json.hbs +1 -1
- package/lib/init/template/approuter/files/mta.yaml.hbs +5 -0
- package/lib/init/template/cf-manifest/files/manifest.yml.hbs +1 -1
- package/lib/init/template/cloud-logging/files/package.json.hbs +3 -3
- package/lib/init/template/dynatrace/files/mta.yaml.hbs +1 -1
- package/lib/init/template/dynatrace/files/package.json.hbs +2 -2
- package/lib/init/template/dynatrace/index.js +2 -1
- package/lib/init/template/enterprise-messaging/files/mta.yaml.hbs +6 -0
- package/lib/init/template/enterprise-messaging/index.js +5 -1
- package/lib/init/template/extensibility/files/package.json.hbs +1 -1
- package/lib/init/template/hana/files/db/package.json +1 -1
- package/lib/init/template/hana/files/package.json.hbs +2 -4
- package/lib/init/template/helm/index.js +13 -22
- package/lib/init/template/helm-unified-runtime/index.js +2 -1
- package/lib/init/template/html5-repo/files/values.yaml.hbs +12 -1
- package/lib/init/template/html5-repo/index.js +10 -5
- package/lib/init/template/http/index.js +1 -1
- package/lib/init/template/ias/files/mta.yaml.hbs +1 -1
- package/lib/init/template/ias/files/sidecar.package.json.hbs +0 -7
- package/lib/init/template/ias/index.js +5 -4
- package/lib/init/template/lint/files/package.json +6 -0
- package/lib/init/template/lint/index.js +61 -204
- package/lib/init/template/mta/files/package.json +1 -1
- package/lib/init/template/multitenancy/files/mta.yaml.hbs +2 -2
- package/lib/init/template/multitenancy/files/package.json.hbs +1 -1
- package/lib/init/template/multitenancy/files/package.sidecar.json.hbs +7 -4
- package/lib/init/template/multitenancy/index.js +3 -0
- package/lib/init/template/nodejs/files/package.json.hbs +5 -2
- package/lib/init/template/redis/files/package.json.hbs +1 -1
- package/lib/init/template/sqlite/files/package.json +1 -1
- package/lib/init/template/toggles/files/package.json.hbs +1 -1
- package/lib/init/template/typescript/files/package.json +1 -3
- package/lib/init/template/workzone-standard/index.js +2 -0
- package/lib/init/template/xsuaa/index.js +2 -6
- package/lib/lint/Linter.js +203 -331
- package/lib/lint/generators.js +52 -46
- package/lib/lint/io.js +77 -289
- package/lib/util/fs.js +2 -1
- package/lib/util/git.js +1 -1
- package/lib/util/glob.js +77 -0
- package/lib/watch/livereload-server.js +3 -4
- package/lib/watch/node-watch.js +3 -4
- package/lib/watch/watched.js +1 -1
- package/npm-shrinkwrap.json +59 -1232
- package/package.json +6 -8
- package/readme.md +1 -1
- package/lib/lint/checks.js +0 -135
|
@@ -709,11 +709,42 @@ function _getServiceComplexTypes(parserContext) {
|
|
|
709
709
|
complexTypeKey = complexTypesKeys[i];
|
|
710
710
|
complexType = parserContext.allComplexTypes[complexTypeKey].Property;
|
|
711
711
|
isOpenType = parserContext.allComplexTypes[complexTypeKey].open;
|
|
712
|
-
|
|
712
|
+
|
|
713
|
+
//S4 might have actions or functions which return a complex type named like the action or function. In this case the complex type must be renamed as else a compile error happens as the result type cannot be found / is a function.
|
|
714
|
+
if (parserContext.allFunctionImports.some(fi => fi[0] === complexTypeKey)) {
|
|
715
|
+
const originalName = complexTypeKey;
|
|
716
|
+
const functionImport = parserContext.allFunctionImports.find(fi => fi[0] === complexTypeKey);
|
|
717
|
+
complexTypeKey = functionImport[0] + 'ReturnType';
|
|
718
|
+
let i = 1;
|
|
719
|
+
while (
|
|
720
|
+
parserContext.allFunctionImports.some(fi => fi[0] === complexTypeKey) ||
|
|
721
|
+
parserContext.allEntitySetMapMC[complexTypeKey] ||
|
|
722
|
+
parserContext.allEntitySetMap[_extractEntityFromNamespace(complexTypeKey)] ||
|
|
723
|
+
parserContext.allEntities.includes(_extractEntityFromNamespace(complexTypeKey))
|
|
724
|
+
) {
|
|
725
|
+
if (i > 1) {
|
|
726
|
+
complexTypeKey = complexTypeKey.slice(0, complexTypeKey.length-1)
|
|
727
|
+
}
|
|
728
|
+
complexTypeKey += i;
|
|
729
|
+
i++;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
//Rename complexType in parserContext for downstream FunctionImport logic
|
|
733
|
+
parserContext.allComplexTypes[complexTypeKey] = parserContext.allComplexTypes[originalName];
|
|
734
|
+
parserContext.allComplexTypes[complexTypeKey]['_attributes'].Name = complexTypeKey
|
|
735
|
+
delete parserContext.allComplexTypes[originalName]
|
|
736
|
+
//Correct Return Type of affected FunctionImports
|
|
737
|
+
const functionImportsWithWrongReturnType = parserContext.allFunctionImports.filter(fi => fi[2] === originalName || fi[2] === `Collection(${originalName})`);
|
|
738
|
+
for (const functionImport of functionImportsWithWrongReturnType) {
|
|
739
|
+
functionImport[2] = functionImport[2].replace(originalName, complexTypeKey);
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
complexTypeCSN += _getServiceComplexType(complexTypeKey, complexType, parserContext, isOpenType);
|
|
713
744
|
if (i !== complexTypesKeys.length - 1) {
|
|
714
|
-
complexTypeCSN
|
|
745
|
+
complexTypeCSN += ",\n";
|
|
715
746
|
} else {
|
|
716
|
-
complexTypeCSN
|
|
747
|
+
complexTypeCSN += "\n";
|
|
717
748
|
}
|
|
718
749
|
}
|
|
719
750
|
return complexTypeCSN;
|
|
@@ -685,6 +685,10 @@ function structElements(context, type, schema) {
|
|
|
685
685
|
//TODO: check if property "name" already exists and has identical cdsType, warn otherwise
|
|
686
686
|
type.elements[name] = cdsType(context, propSchema);
|
|
687
687
|
if (name !== prop) type.elements[name]["@openapi.name"] = prop;
|
|
688
|
+
// Add @mandatory if the property is in the required array
|
|
689
|
+
if (schema.required && schema.required.includes(prop)) {
|
|
690
|
+
type.elements[name]["@mandatory"] = true;
|
|
691
|
+
}
|
|
688
692
|
}
|
|
689
693
|
}
|
|
690
694
|
|
package/lib/index.js
CHANGED
|
@@ -35,10 +35,11 @@ class CdsDk {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
const REQUIRED_CDS_MAJOR =
|
|
38
|
+
const REQUIRED_CDS_MAJOR = 8, REQUIRED_CDS_MINOR = 3
|
|
39
39
|
const [major, minor] = cds.version.split('.').map(Number)
|
|
40
40
|
if (major < REQUIRED_CDS_MAJOR || major === REQUIRED_CDS_MAJOR && minor < REQUIRED_CDS_MINOR) {
|
|
41
41
|
const [dkVersion] = require('../package.json').version.split('.')
|
|
42
|
+
|
|
42
43
|
console.error(`
|
|
43
44
|
This application uses '@sap/cds' version ${major}.${minor}, which is not compatible with the installed '@sap/cds-dk' version ${dkVersion}.
|
|
44
45
|
You can either:
|
|
@@ -48,16 +49,6 @@ if (major < REQUIRED_CDS_MAJOR || major === REQUIRED_CDS_MAJOR && minor < REQUIR
|
|
|
48
49
|
process.exit(1)
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
const EXCLUDED_CDS_MAJOR = 9
|
|
52
|
-
if (major >= EXCLUDED_CDS_MAJOR) {
|
|
53
|
-
const [dkVersion] = require('../package.json').version.split('.')
|
|
54
|
-
console.error(`
|
|
55
|
-
This application uses '@sap/cds' version ${major}, which is not compatible with the installed '@sap/cds-dk' version ${dkVersion}.
|
|
56
|
-
Update '@sap/cds-dk' to the latest version.
|
|
57
|
-
`)
|
|
58
|
-
process.exit(1)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
52
|
cds.extend (cds.constructor) .with (CdsDk)
|
|
62
53
|
|
|
63
54
|
class CdsDkAdd {
|
package/lib/init/constants.js
CHANGED
package/lib/init/merge.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
const { EOL } = require('node:os')
|
|
2
2
|
const { inspect } = require('node:util')
|
|
3
3
|
const cds = require('../cds')
|
|
4
|
-
const
|
|
4
|
+
const YAML = require('yaml')
|
|
5
|
+
const { copy, read, write, exists, path: {resolve, join} } = cds.utils
|
|
5
6
|
const { readYAML, writeYAML, readJSON } = require('../util/fs')
|
|
6
7
|
const { detectIndent } = require('./indent')
|
|
7
8
|
const { colors } = require('../util/term')
|
|
@@ -50,43 +51,7 @@ module.exports.mergeGitignore = async function(into, from) {
|
|
|
50
51
|
const enhanced = target.concat(source.filter(line => !target.includes(line)))
|
|
51
52
|
await write(into, enhanced.join(EOL))
|
|
52
53
|
return enhanced
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* @typedef {Object} MatchedNode
|
|
57
|
-
* @property {string | MatchedNode} in - key path or matched node to start search from
|
|
58
|
-
* @property {Object} where - list of constraints
|
|
59
|
-
*/
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* @typedef {Object} Overwrites
|
|
63
|
-
* @property {(string | MatchedNode)[]} item - path to item to be overwritten
|
|
64
|
-
* @property {string} withValue - replacement string
|
|
65
|
-
*/
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* @typedef {Object} Deletion
|
|
69
|
-
* @property {MatchedNode} item - matched node to delete
|
|
70
|
-
* @property {MatchedNode} [key] - key path to property to delete in node (optional)
|
|
71
|
-
* @property {Object[]} [relationships] - list of relationships to delete
|
|
72
|
-
* @property {string} relationships[].removeProperty - key path to to-be-removed property
|
|
73
|
-
* @property {string[]} relationships[].allWithin - key path to relationship
|
|
74
|
-
*/
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* @typedef {Object} Relationship
|
|
78
|
-
* @property {(string | MatchedNode)[]} insert - source path to matched node
|
|
79
|
-
* @property {(string | MatchedNode)[]} into - target path for inserted relationship
|
|
80
|
-
*/
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* @typedef {Object} MergingSemantics
|
|
84
|
-
* @property {boolean} [forceOverwrite] - overwrite values for existing keys
|
|
85
|
-
* @property {MatchedNode[]} [additions] - matched nodes to be added from source template
|
|
86
|
-
* @property {Overwrites[]} [overwrites] - matched keys to be overwritten with given string
|
|
87
|
-
* @property {Deletion[]} [deletions] - matched nodes to be deleted
|
|
88
|
-
* @property {Relationship[]} [relationships] - relationships to be inserted
|
|
89
|
-
*/
|
|
54
|
+
}
|
|
90
55
|
|
|
91
56
|
/**
|
|
92
57
|
* @param {string | JSON} into - file path or JSON to merge into
|
|
@@ -121,8 +86,8 @@ async function _mergeJSON(into, from, project, semantics) {
|
|
|
121
86
|
}
|
|
122
87
|
|
|
123
88
|
/**
|
|
124
|
-
* @param {string | YAML.Document} into - file path or YAML to merge into
|
|
125
|
-
* @param {string | YAML.Document} from - file path or YAML to merge from
|
|
89
|
+
* @param {string | YAML.Document | object} into - file path or YAML to merge into
|
|
90
|
+
* @param {string | YAML.Document | object} from - file path or YAML to merge from
|
|
126
91
|
* @param {Object} [project] - project descriptor used for Mustache replacements
|
|
127
92
|
* @param {MergingSemantics} [semantics] - merging algorithm semantics
|
|
128
93
|
* @returns {Promise<YAML.Document>} - merged YAML
|
|
@@ -169,11 +134,14 @@ async function _mergeYAML(into, from, project, semantics = {}) {
|
|
|
169
134
|
|
|
170
135
|
const _validateWhere = (node, dict, index) => {
|
|
171
136
|
const _addToMap = entries => entries?.filter(entry => {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
137
|
+
if (typeof entry.in === 'string') return true
|
|
138
|
+
if (typeof entry === 'string' && !entry.where) return false // no random access caching needed for pure key paths
|
|
139
|
+
if (Array.isArray(entry)) entry = entry[0]
|
|
140
|
+
const neededParent = dict.get(entry.in[0])?.node
|
|
141
|
+
return collectionStack.includes(neededParent) // lookbehind in parent collection stack
|
|
142
|
+
// REVISIT: Only look behind until sequence is reached?
|
|
176
143
|
}).forEach(item => {
|
|
144
|
+
if (Array.isArray(item)) item = item[0]
|
|
177
145
|
const json = JSON.parse(String(node))
|
|
178
146
|
const whereFulfilled = Object.entries(item.where).every(([key, value]) =>
|
|
179
147
|
_getProperty(json, key) === value
|
|
@@ -186,7 +154,7 @@ async function _mergeYAML(into, from, project, semantics = {}) {
|
|
|
186
154
|
if (additions) _addToMap(additions)
|
|
187
155
|
if (deletions) _addToMap(deletions.map(deletion => deletion.item))
|
|
188
156
|
if (relationships) _addToMap(relationships?.map(({into: [entry]}) => entry).filter(e => e))
|
|
189
|
-
if (overwrites) _addToMap(overwrites.map(overwrite => overwrite.item
|
|
157
|
+
if (overwrites) _addToMap(overwrites.map(overwrite => overwrite.item))
|
|
190
158
|
}
|
|
191
159
|
|
|
192
160
|
function _traverseYAMLNode(node, index, actions, templateNode) {
|
|
@@ -284,11 +252,23 @@ async function _mergeYAML(into, from, project, semantics = {}) {
|
|
|
284
252
|
overwrites?.forEach(({ item, withValue }) => {
|
|
285
253
|
const keyPath = Array.isArray(item) && typeof item[0] === 'string' ? item[0] : typeof item === 'string' ? item : item[1]
|
|
286
254
|
const inEntry = Array.isArray(item) && typeof item[0] === 'object' ? item[0] : typeof item === 'object' ? item : item[1]
|
|
287
|
-
|
|
255
|
+
let node
|
|
256
|
+
if (inEntry && entryMap.get(inEntry)) {
|
|
257
|
+
node = entryMap.get(inEntry).node // starting from item found in nested array cache
|
|
258
|
+
} else {
|
|
259
|
+
node = collectionStack[collectionStack.length - 1] // starting from root
|
|
260
|
+
}
|
|
288
261
|
const keys = keyPath.split('.')
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
262
|
+
for (const key of keys.slice(0, -1)) {
|
|
263
|
+
if (!node?.get(key) && typeof inEntry === 'string') return // node doesn't exist, will be added by template
|
|
264
|
+
node = node?.get(key) ?? node
|
|
265
|
+
}
|
|
266
|
+
const tail = keys.pop()
|
|
267
|
+
if (!node.get(tail)) {
|
|
268
|
+
node.add({ key: tail, value: withValue })
|
|
269
|
+
} else {
|
|
270
|
+
node.set(tail, withValue)
|
|
271
|
+
}
|
|
292
272
|
})
|
|
293
273
|
|
|
294
274
|
// 4. Delete entries from the project (e.g. separate deployer module when adding mtx)
|
|
@@ -335,7 +315,7 @@ async function _mergeYAML(into, from, project, semantics = {}) {
|
|
|
335
315
|
})
|
|
336
316
|
.filter(item => !entryMap.get(item))
|
|
337
317
|
.forEach(item => {
|
|
338
|
-
if (!templateEntryMap.get(item)) throw 'Error: did not find entry in template for ' + inspect(item, { colors, depth:11 }) + ' in ' + from
|
|
318
|
+
if (!templateEntryMap.get(item)) throw 'Error: did not find entry in template for ' + inspect(item, { colors, depth:11 }) + ' in \n' + from
|
|
339
319
|
const templateNode = templateEntryMap.get(item).node
|
|
340
320
|
item.at !== undefined ? targetNode.items.splice(item.at, 0, templateNode) : targetNode.add(templateNode)
|
|
341
321
|
})
|
|
@@ -352,36 +332,42 @@ async function _mergeYAML(into, from, project, semantics = {}) {
|
|
|
352
332
|
// 7. Create missing relationships
|
|
353
333
|
_traverseYAMLNode(target.contents, null, {
|
|
354
334
|
mergeCollection: (targetNode, templateNode) => {
|
|
355
|
-
|
|
335
|
+
if (!YAML.isSeq(templateNode)) return
|
|
356
336
|
const targetJSON = YAML.parse(String(targetNode))
|
|
357
|
-
const
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
337
|
+
for (const { insert, into } of semantics.relationships ?? []) {
|
|
338
|
+
const [first, ...rest] = into
|
|
339
|
+
const seqPath = rest.find(x => typeof x === 'string') || ''
|
|
340
|
+
const keyPath = rest.length > 1 ? rest.at(-1) : null
|
|
341
|
+
const base = entryMap.get(first)
|
|
342
|
+
if (!base) continue
|
|
343
|
+
const seqNode = seqPath ? _getYAMLProperty(base.node, seqPath) : base.node
|
|
344
|
+
if (seqNode !== targetNode) continue
|
|
345
|
+
const inserts = Array.isArray(insert) ? insert : [insert]
|
|
346
|
+
for (const ins of inserts) {
|
|
347
|
+
const insEntry = entryMap.get(ins)
|
|
348
|
+
if (!insEntry) continue
|
|
349
|
+
const srcNode = insEntry.node, srcJson = insEntry.json
|
|
350
|
+
let key = keyPath
|
|
351
|
+
if (!key && srcNode.get && srcNode.get('name')) key = 'name'
|
|
352
|
+
let cand, duplicate
|
|
353
|
+
if (key) {
|
|
354
|
+
const val = _getProperty(srcJson, key)
|
|
355
|
+
cand = templateNode.items.find(i => YAML.isMap(i) && i.get(key) === val) || { [key]: val }
|
|
356
|
+
duplicate = targetJSON.some(t => t?.[key] === val)
|
|
357
|
+
} else {
|
|
358
|
+
cand = templateNode.items.find(i => JSON.stringify(YAML.parse(String(i))) === JSON.stringify(YAML.parse(String(srcNode)))) || srcNode
|
|
359
|
+
const srcObj = YAML.parse(String(cand))
|
|
360
|
+
duplicate = targetJSON.some(t => JSON.stringify(t) === JSON.stringify(srcObj))
|
|
361
|
+
}
|
|
362
|
+
if (!duplicate) {
|
|
363
|
+
const clone = YAML.parse(YAML.stringify(cand))
|
|
364
|
+
targetNode.add(clone)
|
|
365
|
+
targetJSON.push(clone)
|
|
366
|
+
}
|
|
367
|
+
}
|
|
381
368
|
}
|
|
382
|
-
}
|
|
383
369
|
}
|
|
384
|
-
|
|
370
|
+
}, source.contents)
|
|
385
371
|
|
|
386
372
|
typeof into === 'string' && await writeYAML(into, target)
|
|
387
373
|
return target
|
|
@@ -456,3 +442,41 @@ module.exports.merge = (...src) => {
|
|
|
456
442
|
}
|
|
457
443
|
}
|
|
458
444
|
}
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* @typedef {Object} MatchedNode
|
|
449
|
+
* @property {string | MatchedNode} in - key path or matched node to start search from
|
|
450
|
+
* @property {Object} where - list of constraints
|
|
451
|
+
*/
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* @typedef {Object} Overwrites
|
|
455
|
+
* @property {(string | MatchedNode)[]} item - path to item to be overwritten
|
|
456
|
+
* @property {string} withValue - replacement string
|
|
457
|
+
*/
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* @typedef {Object} Deletion
|
|
461
|
+
* @property {MatchedNode} item - matched node to delete
|
|
462
|
+
* @property {MatchedNode} [key] - key path to property to delete in node (optional)
|
|
463
|
+
* @property {Object[]} [relationships] - list of relationships to delete
|
|
464
|
+
* @property {string} relationships[].removeProperty - key path to to-be-removed property
|
|
465
|
+
* @property {string[]} relationships[].allWithin - key path to relationship
|
|
466
|
+
*/
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* @typedef {Object} Relationship
|
|
470
|
+
* @property {(string | MatchedNode)[]} insert - source path to matched node
|
|
471
|
+
* @property {(string | MatchedNode)[]} into - target path for inserted relationship
|
|
472
|
+
*/
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* @typedef {Object} MergingSemantics
|
|
476
|
+
* @property {boolean} [forceOverwrite] - overwrite values for existing keys
|
|
477
|
+
* @property {MatchedNode[]} [additions] - matched nodes to be added from source template
|
|
478
|
+
* @property {Overwrites[]} [overwrites] - matched keys to be overwritten with given string
|
|
479
|
+
* @property {Deletion[]} [deletions] - matched nodes to be deleted
|
|
480
|
+
* @property {Relationship[]} [relationships] - relationships to be inserted
|
|
481
|
+
*/
|
|
482
|
+
|
package/lib/init/mvn.js
CHANGED
|
@@ -156,15 +156,15 @@ function _scan(mvnParams) {
|
|
|
156
156
|
// a=[x,y,z] => a:x,y,z
|
|
157
157
|
const quoteRegex = /([\w\-.]+)=([\w\-.]+|\[([\w.\-,]+)\])/g
|
|
158
158
|
return [...mvnParams.matchAll(quoteRegex)].map(([,key,value,listValues]) => {
|
|
159
|
-
key = key.startsWith('-
|
|
159
|
+
key = key.startsWith('-') ? key : `-${key}`
|
|
160
160
|
return [key, listValues || value]
|
|
161
161
|
})
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
function _finalize(params) {
|
|
165
165
|
params.set(`-Dstyle.color`, `always`)
|
|
166
|
-
if (LOG._debug) params.set('-X')
|
|
167
|
-
if (LOG._debug) params.set('-e')
|
|
166
|
+
if (LOG._debug && !params.has('-X')) params.set('-X')
|
|
167
|
+
if (LOG._debug && !params.has('-e')) params.set('-e')
|
|
168
168
|
if (process.env.CI) params.set('--batch-mode')
|
|
169
169
|
const final = Array.from(params, ([arg, val]) => val !== null && val !== undefined ? `${arg}=${val}` : arg)
|
|
170
170
|
DEBUG?.(term.highlight('mvn ' + final.join(' ')))
|
|
@@ -194,7 +194,7 @@ module.exports = new class ProjectReader {
|
|
|
194
194
|
hasUI5: _ui5,
|
|
195
195
|
hasMTXRoute: () => _inProd('extensibility') || (_inProd('multitenancy') && !_isJava()),
|
|
196
196
|
hasMTXRouteJava: () => (_inProd('helm-unified-runtime') || _inProd('helm')) && _isJava() && _inProd('multitenancy'),
|
|
197
|
-
imageRegistry: () => exists('chart/values.yaml') ? cds.load.yaml(join(cds.root, 'chart/values.yaml')).global?.image?.registry ?? '<your-container-registry>' : '<your-container-registry>',
|
|
197
|
+
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>',
|
|
198
198
|
extendsApp: _extends,
|
|
199
199
|
}
|
|
200
200
|
|
|
@@ -10,7 +10,12 @@ modules:
|
|
|
10
10
|
- name: {{appName}}-ams-policies-deployer
|
|
11
11
|
type: javascript.nodejs
|
|
12
12
|
{{#isJava}}
|
|
13
|
-
path:
|
|
13
|
+
path: .
|
|
14
|
+
build-parameters:
|
|
15
|
+
builder: custom
|
|
16
|
+
commands:
|
|
17
|
+
- npx cds build --for ams
|
|
18
|
+
build-result: srv/src/gen/policies
|
|
14
19
|
{{/isJava}}
|
|
15
20
|
{{^isJava}}
|
|
16
21
|
path: gen/policies
|
|
@@ -72,6 +72,8 @@ modules:
|
|
|
72
72
|
resources:
|
|
73
73
|
- name: {{appName}}-auth
|
|
74
74
|
type: org.cloudfoundry.managed-service
|
|
75
|
+
requires:
|
|
76
|
+
- name: app-api
|
|
75
77
|
parameters:
|
|
76
78
|
service: xsuaa
|
|
77
79
|
service-plan: application
|
|
@@ -79,3 +81,6 @@ resources:
|
|
|
79
81
|
config:
|
|
80
82
|
xsappname: {{appName}}-${org}-${space}
|
|
81
83
|
tenant-mode: {{#hasMultitenancy}}shared{{/hasMultitenancy}}{{^hasMultitenancy}}dedicated{{/hasMultitenancy}}
|
|
84
|
+
oauth2-configuration:
|
|
85
|
+
redirect-uris:
|
|
86
|
+
- https://~{app-api/app-uri}/**
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"dependencies": {
|
|
3
3
|
"@cap-js/telemetry": ">=0",
|
|
4
4
|
"@grpc/grpc-js": "^1",
|
|
5
|
-
"@opentelemetry/exporter-trace-otlp-grpc": "
|
|
6
|
-
"@opentelemetry/exporter-metrics-otlp-grpc": "
|
|
7
|
-
"@opentelemetry/host-metrics": "
|
|
5
|
+
"@opentelemetry/exporter-trace-otlp-grpc": "<0.200",
|
|
6
|
+
"@opentelemetry/exporter-metrics-otlp-grpc": "<0.200",
|
|
7
|
+
"@opentelemetry/host-metrics": "<0.200"
|
|
8
8
|
},
|
|
9
9
|
"cds": {
|
|
10
10
|
"requires": {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"dependencies": {
|
|
3
3
|
"@cap-js/telemetry": ">=0",
|
|
4
|
-
"@opentelemetry/exporter-metrics-otlp-proto": "
|
|
5
|
-
"@opentelemetry/host-metrics": "
|
|
4
|
+
"@opentelemetry/exporter-metrics-otlp-proto": "<0.200"{{#hasHelm}},
|
|
5
|
+
"@opentelemetry/host-metrics": "<0.200"
|
|
6
6
|
{{/hasHelm}}
|
|
7
7
|
},
|
|
8
8
|
"cds": {
|
|
@@ -24,7 +24,7 @@ module.exports = class extends require('../../plugin') {
|
|
|
24
24
|
|
|
25
25
|
async combine() {
|
|
26
26
|
const project = readProject()
|
|
27
|
-
const { hasMta, hasHelm, hasHelmUnifiedRuntime, isJava, hasMultitenancy, srvPath } = project
|
|
27
|
+
const { appName, hasMta, hasHelm, hasHelmUnifiedRuntime, isJava, hasMultitenancy, srvPath } = project
|
|
28
28
|
|
|
29
29
|
if (hasMta) {
|
|
30
30
|
const dynatrace = {
|
|
@@ -48,6 +48,7 @@ module.exports = class extends require('../../plugin') {
|
|
|
48
48
|
into: [mtxSidecar, 'requires', 'name']
|
|
49
49
|
})
|
|
50
50
|
}
|
|
51
|
+
project.uppercaseStrippedAppName = appName.replace(/-/g, '').toUpperCase().slice(0, 16),
|
|
51
52
|
await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', {
|
|
52
53
|
with: project, additions, relationships
|
|
53
54
|
})
|
|
@@ -2,7 +2,7 @@ const cds = require('../../../cds')
|
|
|
2
2
|
const { read, yaml: YAML } = cds.utils
|
|
3
3
|
const { readProject } = require('../../projectReader')
|
|
4
4
|
const { merge } = require('../../merge')
|
|
5
|
-
const { srv4, enterpriseMessaging } = require('../../registries/mta')
|
|
5
|
+
const { srv4, enterpriseMessaging, xsuaa } = require('../../registries/mta')
|
|
6
6
|
|
|
7
7
|
module.exports = class EnterpriseMessagingTemplate extends require('../../plugin') {
|
|
8
8
|
|
|
@@ -58,6 +58,10 @@ module.exports = class EnterpriseMessagingTemplate extends require('../../plugin
|
|
|
58
58
|
|
|
59
59
|
if (hasXsuaa) {
|
|
60
60
|
if (hasMta) {
|
|
61
|
+
await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', {
|
|
62
|
+
project,
|
|
63
|
+
additions: [xsuaa]
|
|
64
|
+
})
|
|
61
65
|
project['em-service-name'] = YAML.parse(await read('mta.yaml'))?.resources?.find(r => r?.parameters?.service === 'enterprise-messaging')?.name
|
|
62
66
|
} else {
|
|
63
67
|
project['em-service-name'] = `${appName}-messaging`
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"node": "^22.0.0"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"start": "node node_modules/@sap/hdi-deploy/deploy.js --use-hdb",
|
|
11
|
+
"start": "node node_modules/@sap/hdi-deploy/deploy.js --use-hdb --parameter com.sap.hana.di.table/try_fast_table_migration=true",
|
|
12
12
|
"build": "npm i && npx cds build .. --for hana --production"
|
|
13
13
|
}
|
|
14
14
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const { join } = require('path')
|
|
2
|
+
const yaml = require('yaml')
|
|
2
3
|
const cds = require('../../../cds')
|
|
3
|
-
const { exists, rimraf, copy, readFileSync
|
|
4
|
+
const { exists, rimraf, copy, readFileSync } = cds.utils
|
|
4
5
|
const { readProject } = require('../../projectReader')
|
|
5
6
|
const { merge } = require('../../merge')
|
|
6
7
|
const { ask4 } = require('../../../util/question')
|
|
@@ -46,43 +47,33 @@ module.exports = class HelmTemplate extends require('../../plugin') {
|
|
|
46
47
|
async run() {
|
|
47
48
|
const project = readProject()
|
|
48
49
|
project.domain = 'abc.com'
|
|
49
|
-
project.registry = 'registry-
|
|
50
|
+
project.registry = 'registry-server'
|
|
50
51
|
project.imagePullSecret = 'docker-registry'
|
|
51
52
|
project.tag = 'latest'
|
|
52
53
|
|
|
53
|
-
if (cds.cli.command
|
|
54
|
-
let registry = 'registry-
|
|
54
|
+
if (cds.cli.command === 'add' && !HelmTemplate.hasInProduction()) {
|
|
55
|
+
let registry = 'registry-server', tag = 'latest', domain = 'abc.com'
|
|
55
56
|
|
|
56
|
-
// read domain using kubectl
|
|
57
57
|
try {
|
|
58
|
-
const
|
|
59
|
-
const domainStartIndex =
|
|
60
|
-
if (domainStartIndex !== -1)
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
} catch (error) {
|
|
64
|
-
// ignore
|
|
65
|
-
}
|
|
58
|
+
const domainGuess = execSync(`kubectl config view --minify --output jsonpath="{.clusters[*].cluster.server}"`, { stdio: "pipe" }).toString()
|
|
59
|
+
const domainStartIndex = domainGuess.indexOf('api.')
|
|
60
|
+
if (domainStartIndex !== -1) domain = domainGuess.substring(domainStartIndex + 4)
|
|
61
|
+
} catch (error) { /* ignore */ }
|
|
66
62
|
|
|
67
63
|
// read project.registry
|
|
68
64
|
if (exists('containerize.yaml')) {
|
|
69
65
|
const containerizeYamlFile = readFileSync(join(cds.root, 'containerize.yaml'), 'utf8')
|
|
70
|
-
const
|
|
71
|
-
registry =
|
|
72
|
-
tag =
|
|
66
|
+
const containerizeYaml = yaml.parseDocument(containerizeYamlFile).toJS()
|
|
67
|
+
registry = containerizeYaml.repository
|
|
68
|
+
tag = containerizeYaml.tag
|
|
73
69
|
}
|
|
74
70
|
|
|
75
|
-
let imagePullSecretInput = 'docker-registry'
|
|
76
71
|
if (!cds.cli.options['y']) {
|
|
77
|
-
const [
|
|
78
|
-
|
|
79
|
-
domain = domainAns || domain
|
|
80
|
-
imagePullSecretInput = imagePullSecretAns || imagePullSecretInput
|
|
72
|
+
const [registryAns] = await ask4(`registry server (${registry}): `)
|
|
81
73
|
registry = registryAns || registry
|
|
82
74
|
}
|
|
83
75
|
|
|
84
76
|
project.domain = domain
|
|
85
|
-
project.imagePullSecret = imagePullSecretInput
|
|
86
77
|
project.registry = registry
|
|
87
78
|
project.tag = tag
|
|
88
79
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const cds = require('../../..')
|
|
2
|
-
const
|
|
2
|
+
const yaml = require('yaml')
|
|
3
|
+
const { rimraf, exists, readFileSync } = cds.utils
|
|
3
4
|
const { join } = require('path')
|
|
4
5
|
|
|
5
6
|
const { readProject } = require('../../projectReader')
|
|
@@ -5,11 +5,22 @@ html5-apps-repo-host:
|
|
|
5
5
|
html5-apps-deployer:
|
|
6
6
|
env:
|
|
7
7
|
SAP_CLOUD_SERVICE: {{strippedAppName}}.service
|
|
8
|
+
{{#hasIas}}
|
|
9
|
+
IAS_DEPENDENCY_NAME: {{appName}}-ias-dependency
|
|
10
|
+
{{/hasIas}}
|
|
8
11
|
image:
|
|
9
12
|
repository: {{appName}}-html5-deployer
|
|
10
13
|
bindings:
|
|
14
|
+
{{#hasXsuaa}}
|
|
11
15
|
xsuaa:
|
|
12
16
|
serviceInstanceName: xsuaa
|
|
17
|
+
{{/hasXsuaa}}
|
|
18
|
+
{{#hasIas}}
|
|
19
|
+
ias:
|
|
20
|
+
serviceInstanceName: identity
|
|
21
|
+
parameters:
|
|
22
|
+
credential-type: X509_GENERATED
|
|
23
|
+
{{/hasIas}}
|
|
13
24
|
destination:
|
|
14
25
|
serviceInstanceName: destination
|
|
15
26
|
html5-apps-repo:
|
|
@@ -26,7 +37,7 @@ html5-apps-deployer:
|
|
|
26
37
|
- configMapRef:
|
|
27
38
|
name: "{{ .Release.Name }}-html5-apps-deployer-configmap"
|
|
28
39
|
<%={{ }}=%>
|
|
29
|
-
backendDestinations:
|
|
40
|
+
backendDestinations:
|
|
30
41
|
srv-api:
|
|
31
42
|
service: srv
|
|
32
43
|
destination:
|