@sap/cds-dk 9.1.3 → 9.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -0
- package/bin/bind.js +2 -0
- package/bin/cds.js +2 -0
- package/bin/repl.js +4 -2
- package/bin/up.js +12 -2
- package/bin/util/log.js +8 -1
- package/bin/version.js +20 -15
- package/lib/bind/shared.js +6 -2
- package/lib/build/plugins/helm/files/subcharts/web-application/Chart.yaml +1 -1
- package/lib/build/plugins/helm/files/subcharts/web-application/templates/_helpers.tpl +1 -1
- package/lib/build/plugins/helm/files/subcharts/web-application/templates/deployment.yaml +8 -0
- package/lib/build/plugins/helm/files/subcharts/web-application/templates/virtual-service.yaml +38 -0
- package/lib/build/plugins/helm/files/subcharts/web-application/values.schema.json +15 -0
- package/lib/build/plugins/helm/files/subcharts/web-application/values.yaml +12 -9
- package/lib/build/plugins/helm/index.js +1 -1
- package/lib/build/provider/hana/index.js +5 -4
- package/lib/build/provider/hana/template/.hdiconfig-all +6 -0
- package/lib/compile/to-xsuaa.js +14 -4
- package/lib/deploy/to-hana/hana.js +1 -1
- package/lib/deploy/to-hana/hdiDeployUtil.js +1 -1
- package/lib/init/constants.js +5 -3
- package/lib/init/index.js +6 -1
- package/lib/init/merge.js +7 -3
- package/lib/init/projectReader.js +7 -2
- package/lib/init/registries/mta.js +6 -0
- package/lib/init/template/ams/files/values.yaml.hbs +5 -0
- package/lib/init/template/approuter/files/containerize.yaml.hbs +1 -1
- package/lib/init/template/approuter/files/values.yaml.hbs +1 -5
- package/lib/init/template/attachments/index.js +1 -1
- package/lib/init/template/audit-logging/index.js +1 -1
- package/lib/init/template/data/as-json.js +4 -3
- package/lib/init/template/data/index.js +1 -0
- package/lib/init/template/destination/files/mta.yaml.hbs +1 -20
- package/lib/init/template/extension/index.js +1 -1
- package/lib/init/template/github-actions/files/cf-github-deploy/action.yaml +48 -0
- package/lib/init/template/github-actions/files/cf-setup/action.yaml +53 -0
- package/lib/init/template/github-actions/files/kyma-info/action.yaml +37 -0
- package/lib/init/template/github-actions/files/kyma-setup/action.yaml +64 -0
- package/lib/init/template/github-actions/files/workflows/cf.yaml.hbs +52 -0
- package/lib/init/template/github-actions/files/workflows/kyma.yaml.hbs +39 -0
- package/lib/init/template/github-actions/files/workflows/test.yaml.hbs +21 -0
- package/lib/init/template/github-actions/index.js +69 -0
- package/lib/init/template/helm/index.js +5 -1
- package/lib/init/template/html5-repo/files/containerize.yaml.hbs +4 -4
- package/lib/init/template/html5-repo/files/mta.yaml.hbs +24 -0
- package/lib/init/template/html5-repo/files/values.yaml.hbs +2 -1
- package/lib/init/template/html5-repo/index.js +9 -3
- package/lib/init/template/http/index.js +4 -4
- package/lib/init/template/ias/files/package.json.hbs +7 -0
- package/lib/init/template/ias/files/values.yaml.hbs +1 -4
- package/lib/init/template/ias/index.js +2 -1
- package/lib/init/template/kyma/index.js +10 -0
- package/lib/init/template/lint/index.js +6 -11
- package/lib/init/template/malware-scanner/index.js +1 -1
- package/lib/init/template/multitenancy/files/values.yaml.hbs +53 -1
- package/lib/init/template/multitenancy/index.js +0 -13
- package/lib/init/template/nodejs/files/.vscode/settings.json +2 -2
- package/lib/init/template/notifications/index.js +1 -1
- package/lib/init/template/pipeline/files/Jenkinsfile +2 -2
- package/lib/init/template/pipeline/index.js +1 -1
- package/lib/init/template/portal/files/containerize.yaml.hbs +15 -0
- package/lib/init/template/portal/files/values.yaml.hbs +1 -1
- package/lib/init/template/portal/index.js +9 -1
- package/lib/init/template/postgres/index.js +1 -1
- package/lib/init/template/sample/index.js +1 -1
- package/lib/init/template/test/index.js +1 -1
- package/lib/init/template/tiny-sample/index.js +1 -1
- package/lib/init/template/typescript/index.js +1 -1
- package/lib/init/template/workzone-standard/index.js +13 -4
- package/lib/init/template/xsuaa/files/mta.yaml.hbs +8 -0
- package/lib/init/template/xsuaa/index.js +11 -0
- package/lib/init/template.js +38 -26
- package/lib/lint/eslintHelp.json +1 -1
- package/lib/util/cf.js +7 -7
- package/lib/watch/watched.js +1 -1
- package/npm-shrinkwrap.json +24 -24
- package/package.json +1 -1
- /package/lib/init/template/html5-repo/files/{ui-resources/package.json.hbs → html5-deployer.package.json.hbs} +0 -0
|
@@ -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, html5RepoHost, html5Runtime, appDeployer, approuter, mtxSidecar4 } = require('../../registries/mta')
|
|
4
|
+
const { srv4, html5RepoHost, html5Runtime, xsuaa, appDeployer, approuter, mtxSidecar4 } = require('../../registries/mta')
|
|
5
5
|
const { odataApi } = require('../../registries/xs-app')
|
|
6
6
|
const { exists } = require('../../../cds').utils
|
|
7
7
|
const { renderAndCopy } = require('../../template')
|
|
@@ -51,7 +51,7 @@ module.exports = class Html5RepoTemplate extends require('../../plugin') {
|
|
|
51
51
|
|
|
52
52
|
async combine() {
|
|
53
53
|
const project = readProject()
|
|
54
|
-
const { isJava, srvPath, appPath, hasMta, hasMultitenancy, hasWorkzoneStandard, hasHelm, hasHelmUnifiedRuntime, hasApprouter, hasContainerize, apps } = project
|
|
54
|
+
const { isJava, srvPath, appPath, hasMta, hasXsuaa, hasMultitenancy, hasWorkzoneStandard, hasHelm, hasHelmUnifiedRuntime, hasApprouter, hasContainerize, apps } = project
|
|
55
55
|
|
|
56
56
|
await Promise.all(apps.map(async ({ app }) => {
|
|
57
57
|
project.app = app
|
|
@@ -97,6 +97,12 @@ module.exports = class Html5RepoTemplate extends require('../../plugin') {
|
|
|
97
97
|
into: [isJava ? srv : mtxSidecar4('gen/mtx/sidecar'), 'requires', 'name']
|
|
98
98
|
})
|
|
99
99
|
}
|
|
100
|
+
if (hasXsuaa) {
|
|
101
|
+
relationships.push({
|
|
102
|
+
insert: [xsuaa, 'name'],
|
|
103
|
+
into: [appDeployer, 'requires']
|
|
104
|
+
})
|
|
105
|
+
}
|
|
100
106
|
await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', {
|
|
101
107
|
with: project,
|
|
102
108
|
additions,
|
|
@@ -111,7 +117,7 @@ module.exports = class Html5RepoTemplate extends require('../../plugin') {
|
|
|
111
117
|
await merge(__dirname, '/files/containerize.yaml.hbs').into('containerize.yaml', { with: project, additions })
|
|
112
118
|
}
|
|
113
119
|
if (hasHelm || hasHelmUnifiedRuntime) {
|
|
114
|
-
await renderAndCopy(join(__dirname, 'files/
|
|
120
|
+
await renderAndCopy(join(__dirname, 'files/html5-deployer.package.json.hbs'), 'app/html5-deployer/package.json', project)
|
|
115
121
|
await merge(__dirname, 'files/values.yaml.hbs').into('chart/values.yaml', { with: project })
|
|
116
122
|
}
|
|
117
123
|
}
|
|
@@ -163,7 +163,7 @@ module.exports = class HttpTemplate extends require('../../plugin') {
|
|
|
163
163
|
const key = Object.keys(e.keys)[0] // draft keys are always single
|
|
164
164
|
delete entityData[key] // draft keys should always by auto generated (either UUID or through custom logic), so remove them from the payload
|
|
165
165
|
const postBody = JSON.stringify(entityData, null, 2)
|
|
166
|
-
generateDraftRequests(requests, requestTitle, url, headers, headerAuth, postBody, key)
|
|
166
|
+
generateDraftRequests(requests, requestTitle, url, headers, headerAuth, postBody, key, service)
|
|
167
167
|
}
|
|
168
168
|
else {
|
|
169
169
|
const postBody = JSON.stringify(entityData, null, 2)
|
|
@@ -198,14 +198,14 @@ module.exports = class HttpTemplate extends require('../../plugin') {
|
|
|
198
198
|
this.#write(requests, serviceName)
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
-
function generateDraftRequests(requests, title, url, headers, headerAuth, postBody, key) {
|
|
201
|
+
function generateDraftRequests(requests, title, url, headers, headerAuth, postBody, key, service) {
|
|
202
202
|
const nameDraftsCreate = slug(title+'_Draft_POST')
|
|
203
203
|
requests.push(`${title} Drafts GET\n# @name ${slug(title+'_Drafts_GET')}\nGET ${url}?$filter=(IsActiveEntity eq false)\n${headerAuth}\n`) // unencoded URL for better readability (client can handle this)
|
|
204
204
|
requests.push(`${title} Draft POST\n# @name ${nameDraftsCreate}\nPOST ${url}\n${headers}\n\n${postBody}\n`)
|
|
205
205
|
requests.push(`\n### Result from POST request above\n@draftID={{${nameDraftsCreate}.response.body.$.${key}}}\n`)
|
|
206
206
|
requests.push(`${title} Draft PATCH\n# @name ${slug(title+'_Draft_Patch')}\nPATCH ${url}(${key}={{draftID}},IsActiveEntity=false)\n${headers}\n\n${postBody}\n`)
|
|
207
|
-
requests.push(`${title} Draft Prepare\n# @name ${slug(title+'_Draft_Prepare')}\nPOST ${url}(${key}={{draftID}},IsActiveEntity=false)
|
|
208
|
-
requests.push(`${title} Draft Activate\n# @name ${slug(title+'_Draft_Activate')}\nPOST ${url}(${key}={{draftID}},IsActiveEntity=false)
|
|
207
|
+
requests.push(`${title} Draft Prepare\n# @name ${slug(title+'_Draft_Prepare')}\nPOST ${url}(${key}={{draftID}},IsActiveEntity=false)/${service.name}.draftPrepare\n${headers}\n\n{}\n`)
|
|
208
|
+
requests.push(`${title} Draft Activate\n# @name ${slug(title+'_Draft_Activate')}\nPOST ${url}(${key}={{draftID}},IsActiveEntity=false)/${service.name}.draftActivate\n${headers}\n\n{}\n`)
|
|
209
209
|
}
|
|
210
210
|
|
|
211
211
|
function slug(str) {
|
|
@@ -9,13 +9,20 @@
|
|
|
9
9
|
{{#profile}}
|
|
10
10
|
"[{{profile}}]": {
|
|
11
11
|
{{/profile}}
|
|
12
|
+
{{#shortcut}}
|
|
13
|
+
"auth": "ias"
|
|
14
|
+
{{/shortcut}}
|
|
15
|
+
{{^shortcut}}
|
|
12
16
|
"auth": {
|
|
13
17
|
"kind": "ias"
|
|
14
18
|
}
|
|
19
|
+
{{/shortcut}}
|
|
20
|
+
|
|
15
21
|
{{#profile}}
|
|
16
22
|
}
|
|
17
23
|
{{/profile}}
|
|
18
24
|
}
|
|
25
|
+
|
|
19
26
|
{{#isNodejs}}
|
|
20
27
|
}
|
|
21
28
|
{{/isNodejs}}
|
|
@@ -29,10 +29,6 @@ identity:
|
|
|
29
29
|
servicePlanName: application
|
|
30
30
|
parameters:
|
|
31
31
|
display-name: {{appName}}
|
|
32
|
-
{{#hasAms}}
|
|
33
|
-
authorization:
|
|
34
|
-
enabled: true
|
|
35
|
-
{{/hasAms}}
|
|
36
32
|
{{#hasMultitenancy}}
|
|
37
33
|
multi-tenant: true
|
|
38
34
|
{{/hasMultitenancy}}
|
|
@@ -50,3 +46,4 @@ identity:
|
|
|
50
46
|
- https://*.{{ tpl .Values.global.domain . }}/*/logout.html
|
|
51
47
|
<%={{ }}=%>
|
|
52
48
|
{{/hasApprouter}}
|
|
49
|
+
|
|
@@ -20,6 +20,8 @@ module.exports = class IasTemplate extends require('../../plugin') {
|
|
|
20
20
|
async run() {
|
|
21
21
|
const project = readProject()
|
|
22
22
|
const { configFile, isNodejs } = project
|
|
23
|
+
project.profile ??= 'production'
|
|
24
|
+
project.shortcut = typeof (await read(configFile)).cds?.requires?.auth !== 'object'
|
|
23
25
|
await merge(__dirname, 'files/package.json.hbs').into(configFile, { project, forceOverwrite: true })
|
|
24
26
|
if (isNodejs) await sort('package.json', 'dependencies')
|
|
25
27
|
}
|
|
@@ -70,7 +72,6 @@ module.exports = class IasTemplate extends require('../../plugin') {
|
|
|
70
72
|
const identity = { in: 'dependencies', where: { 'alias': 'identity' } }
|
|
71
73
|
await merge(__dirname, 'files/Chart.yaml.hbs').into('chart/Chart.yaml', { project, additions: [identity] })
|
|
72
74
|
await merge(__dirname, 'files/values.yaml.hbs').into('chart/values.yaml', { project })
|
|
73
|
-
// TODO: MTX, approuter
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
if (hasCfManifest) {
|
|
@@ -5,8 +5,11 @@ const cds = require('../../../cds')
|
|
|
5
5
|
const { merge } = require('../../merge')
|
|
6
6
|
const { dim, bold } = require('../../../util/term')
|
|
7
7
|
|
|
8
|
-
const
|
|
9
|
-
|
|
8
|
+
const ESLINT_LANGS_FOR_FILE_TYPE = {
|
|
9
|
+
cds: ['cds', 'csn'],
|
|
10
|
+
csv: ['csv', 'csv (semicolon)', 'tsv', 'tab'],
|
|
11
|
+
js: ['javascript'],
|
|
12
|
+
ts: ['typescript']
|
|
10
13
|
}
|
|
11
14
|
|
|
12
15
|
/**
|
|
@@ -54,15 +57,7 @@ module.exports = class LintTemplate extends require('../../plugin') {
|
|
|
54
57
|
await this.#addEslintPluginConfig()
|
|
55
58
|
|
|
56
59
|
// Generate VS Code extension settings
|
|
57
|
-
const
|
|
58
|
-
const extensions = new Set(ALLOWED_FILE_EXTENSIONS.map((ext) => path.extname(ext).replace('.', '')))
|
|
59
|
-
for (const ext of extensions) {
|
|
60
|
-
if (ext in VSCODE_FILE_ASSOCIATIONS) {
|
|
61
|
-
for (const assoc of VSCODE_FILE_ASSOCIATIONS[ext]) {
|
|
62
|
-
extensions.add(assoc)
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
60
|
+
const extensions = new Set(Object.values(ESLINT_LANGS_FOR_FILE_TYPE).flat())
|
|
66
61
|
await io.sanitizeVscodeSettings(
|
|
67
62
|
path.join(cds.root, '.vscode/settings.json'),
|
|
68
63
|
Array.from(extensions),
|
|
@@ -5,7 +5,7 @@ const { srv4, malwareScanner } = require('../../registries/mta')
|
|
|
5
5
|
module.exports = class MalwareScannerTemplate extends require('../../plugin') {
|
|
6
6
|
|
|
7
7
|
static help() {
|
|
8
|
-
return 'SAP Malware Scanning Service'
|
|
8
|
+
return 'SAP BTP Malware Scanning Service'
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
static hasInProduction(env) {
|
|
@@ -2,8 +2,14 @@
|
|
|
2
2
|
srv:
|
|
3
3
|
bindings:
|
|
4
4
|
{{#isJava}}
|
|
5
|
+
{{#hasXsuaa}}
|
|
5
6
|
saas-registry:
|
|
6
7
|
serviceInstanceName: saas-registry
|
|
8
|
+
{{/hasXsuaa}}
|
|
9
|
+
{{^hasXsuaa}}
|
|
10
|
+
subscription-manager:
|
|
11
|
+
serviceInstanceName: subscription-manager
|
|
12
|
+
{{/hasXsuaa}}
|
|
7
13
|
{{/isJava}}
|
|
8
14
|
service-manager:
|
|
9
15
|
serviceInstanceName: service-manager
|
|
@@ -14,10 +20,13 @@ srv:
|
|
|
14
20
|
service-manager:
|
|
15
21
|
serviceOfferingName: service-manager
|
|
16
22
|
servicePlanName: container
|
|
23
|
+
{{#hasXsuaa}}
|
|
17
24
|
saas-registry:
|
|
18
25
|
serviceOfferingName: saas-registry
|
|
19
26
|
servicePlanName: application
|
|
20
27
|
parameters:
|
|
28
|
+
appName: {{appName}}-{{#literal}}{{ .Release.Namespace }}{{/literal}}
|
|
29
|
+
xsappname: {{appName}}-{{#literal}}{{ .Release.Namespace }}{{/literal}}
|
|
21
30
|
displayName: {{appName}}
|
|
22
31
|
description: {{appDescription}}
|
|
23
32
|
category: "CAP Application"
|
|
@@ -25,21 +34,64 @@ saas-registry:
|
|
|
25
34
|
onSubscriptionAsync: true
|
|
26
35
|
onUnSubscriptionAsync: true
|
|
27
36
|
onUpdateDependenciesAsync: true
|
|
28
|
-
callbackTimeoutMillis: 300000
|
|
37
|
+
callbackTimeoutMillis: 300000{{#isJava}}{{#literal}}
|
|
38
|
+
getDependencies: https://{{ .Release.Name }}-srv-{{ .Release.Namespace }}.{{ .Values.global.domain }}/mt/v1.0/subscriptions/dependencies
|
|
39
|
+
onSubscription: https://{{ .Release.Name }}-srv-{{ .Release.Namespace }}.{{ .Values.global.domain }}/mt/v1.0/subscriptions/tenants/{tenantId}
|
|
40
|
+
{{/literal}}{{/isJava}}{{#isNodejs}}{{#literal}}
|
|
41
|
+
getDependencies: https://{{ .Release.Name }}-sidecar-{{ .Release.Namespace }}.{{ .Values.global.domain }}/-/cds/saas-provisioning/dependencies
|
|
42
|
+
onSubscription: https://{{ .Release.Name }}-sidecar-{{ .Release.Namespace }}.{{ .Values.global.domain }}/-/cds/saas-provisioning/tenant/{tenantId}
|
|
43
|
+
{{/literal}}{{/isNodejs}}
|
|
44
|
+
{{/hasXsuaa}}
|
|
45
|
+
|
|
46
|
+
{{^hasXsuaa}}
|
|
47
|
+
subscription-manager:
|
|
48
|
+
serviceOfferingName: subscription-manager
|
|
49
|
+
servicePlanName: provider
|
|
50
|
+
parameters:
|
|
51
|
+
appCallbacks:
|
|
52
|
+
dependenciesCallbacks:
|
|
53
|
+
{{#literal}}url: https://{{ .Release.Name }}-sidecar-{{ .Release.Namespace }}.cert.{{ .Values.global.domain }}/-/cds/sms-provisioning/dependencies/{app_tid}{{/literal}}
|
|
54
|
+
subscriptionCallbacks:
|
|
55
|
+
{{#literal}}url: https://{{ .Release.Name }}-sidecar-{{ .Release.Namespace }}.cert.{{ .Values.global.domain }}/-/cds/sms-provisioning/tenant/{app_tid}{{/literal}}
|
|
56
|
+
appName: {{appName}}
|
|
57
|
+
applicationType: application
|
|
58
|
+
category: "CAP Application"
|
|
59
|
+
description: {{appDescription}}
|
|
60
|
+
displayName: {{appName}}
|
|
61
|
+
subscribeEnable: true
|
|
62
|
+
unsubscribeEnable: true
|
|
63
|
+
iasServiceInstanceName: {{appName}}-identity
|
|
64
|
+
{{/hasXsuaa}}
|
|
65
|
+
|
|
29
66
|
sidecar:
|
|
30
67
|
bindings:
|
|
31
68
|
{{#hasXsuaa}}
|
|
32
69
|
auth:
|
|
33
70
|
serviceInstanceName: xsuaa
|
|
34
71
|
{{/hasXsuaa}}
|
|
72
|
+
{{#hasIas}}
|
|
73
|
+
auth:
|
|
74
|
+
serviceInstanceName: identity
|
|
75
|
+
{{/hasIas}}
|
|
35
76
|
{{#isNodejs}}
|
|
77
|
+
{{#hasXsuaa}}
|
|
36
78
|
saas-registry:
|
|
37
79
|
serviceInstanceName: saas-registry
|
|
80
|
+
{{/hasXsuaa}}
|
|
81
|
+
{{^hasXsuaa}}
|
|
82
|
+
subscription-manager:
|
|
83
|
+
serviceInstanceName: subscription-manager
|
|
84
|
+
{{/hasXsuaa}}
|
|
38
85
|
{{/isNodejs}}
|
|
39
86
|
service-manager:
|
|
40
87
|
serviceInstanceName: service-manager
|
|
41
88
|
image:
|
|
42
89
|
repository: {{appName}}-sidecar
|
|
90
|
+
{{#hasIas}}
|
|
91
|
+
expose:
|
|
92
|
+
gateway: default/kyma-mtls-gateway
|
|
93
|
+
{{#literal}}host: https://{{ .Release.Name }}-sidecar-{{ .Release.Namespace }}.cert.{{ .Values.global.domain }}{{/literal}}
|
|
94
|
+
{{/hasIas}}
|
|
43
95
|
resources:
|
|
44
96
|
limits:
|
|
45
97
|
ephemeral-storage: 1G
|
|
@@ -85,20 +85,7 @@ module.exports = class MultitenancyTemplate extends require('../../plugin') {
|
|
|
85
85
|
if (hasHelm || hasHelmUnifiedRuntime) {
|
|
86
86
|
await merge(__dirname, 'files/values.yaml.hbs').into('chart/values.yaml', { with: project })
|
|
87
87
|
const applicationWorkload = hasApprouter ? 'approuter' : 'srv'
|
|
88
|
-
const mtServer = isNodejs ? 'sidecar' : 'srv'
|
|
89
|
-
const prefix = `https://{{ .Release.Name }}-${mtServer}-{{ .Release.Namespace }}.{{ .Values.global.domain }}`
|
|
90
|
-
const getDependencies = `${prefix}${isNodejs ? '/-/cds/saas-provisioning' : '/mt/v1.0/subscriptions'}/dependencies`
|
|
91
|
-
const onSubscription = `${prefix}${isNodejs ? '/-/cds/saas-provisioning/tenant/{tenantId}' : '/mt/v1.0/subscriptions/tenants/{tenantId}'}`
|
|
92
88
|
await merge({
|
|
93
|
-
'saas-registry': {
|
|
94
|
-
parameters: {
|
|
95
|
-
xsappname: `${appName}-{{ .Release.Namespace }}`,
|
|
96
|
-
appName: `${appName}-{{ .Release.Namespace }}`,
|
|
97
|
-
appUrls: {
|
|
98
|
-
getDependencies, onSubscription
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
},
|
|
102
89
|
...(isNodejs) && { sidecar: { env: {
|
|
103
90
|
SUBSCRIPTION_URL: `https://\${tenant_subdomain}-{{ .Release.Name }}-${applicationWorkload}-{{ .Release.Namespace }}.{{ .Values.global.domain }}`
|
|
104
91
|
}}},
|
|
@@ -15,7 +15,7 @@ module.exports = class NotificationsTemplate extends require('../../plugin') {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
static hasInProduction(env) {
|
|
18
|
-
return !!env.requires?.notifications
|
|
18
|
+
return !!env.requires?.notifications || readProject().dependencies?.['@cap-js/notifications']
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
async canRun() {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env groovy
|
|
1
|
+
#!/usr/bin/env groovy
|
|
2
2
|
|
|
3
3
|
/*
|
|
4
4
|
* This file bootstraps the codified Continuous Delivery pipeline for extensions of SAP solutions such as SAP S/4HANA.
|
|
@@ -9,4 +9,4 @@
|
|
|
9
9
|
|
|
10
10
|
@Library('piper-lib-os') _
|
|
11
11
|
|
|
12
|
-
piperPipeline script: this
|
|
12
|
+
piperPipeline script: this
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
modules:
|
|
3
|
+
- name: {{appName}}-portal-deployer
|
|
4
|
+
build-parameters:
|
|
5
|
+
buildpack:
|
|
6
|
+
{{#hasHelmUnifiedRuntime}}
|
|
7
|
+
builder: proxy-unified-runtime-dmz.int.repositories.cloud.sap/builder/noble
|
|
8
|
+
{{/hasHelmUnifiedRuntime}}
|
|
9
|
+
{{^hasHelmUnifiedRuntime}}
|
|
10
|
+
type: nodejs
|
|
11
|
+
builder: builder-jammy-base
|
|
12
|
+
{{/hasHelmUnifiedRuntime}}
|
|
13
|
+
path: app/portal
|
|
14
|
+
env:
|
|
15
|
+
BP_NODE_RUN_SCRIPTS: ""
|
|
@@ -29,7 +29,7 @@ module.exports = class PortalTemplate extends require('../../plugin') {
|
|
|
29
29
|
|
|
30
30
|
async combine() {
|
|
31
31
|
const project = readProject()
|
|
32
|
-
const { isJava, hasMta, srvPath, hasHtml5Repo, hasXsuaa, hasApprouter, hasMultitenancy, hasHelm, hasHelmUnifiedRuntime } = project
|
|
32
|
+
const { appName, isJava, hasMta, srvPath, hasHtml5Repo, hasXsuaa, hasApprouter, hasMultitenancy, hasHelm, hasHelmUnifiedRuntime, hasContainerize } = project
|
|
33
33
|
|
|
34
34
|
if (hasMultitenancy) {
|
|
35
35
|
await merge(__dirname, 'files/package.sidecar.json').into('mtx/sidecar/package.json')
|
|
@@ -81,6 +81,14 @@ module.exports = class PortalTemplate extends require('../../plugin') {
|
|
|
81
81
|
})
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
if (hasContainerize) {
|
|
85
|
+
const additions = [{
|
|
86
|
+
in: 'modules',
|
|
87
|
+
where: { name: `${appName}-portal-deployer` }
|
|
88
|
+
}]
|
|
89
|
+
await merge(__dirname, '/files/containerize.yaml.hbs').into('containerize.yaml', { with: project, additions })
|
|
90
|
+
}
|
|
91
|
+
|
|
84
92
|
if (hasHelm || hasHelmUnifiedRuntime) {
|
|
85
93
|
await merge(__dirname, 'files/values.yaml.hbs').into('chart/values.yaml', { with: project })
|
|
86
94
|
}
|
|
@@ -18,7 +18,7 @@ module.exports = class PostgresTemplate extends require('../../plugin') {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
static hasInProduction(env) {
|
|
21
|
-
return env.requires?.db?.kind === 'postgres'
|
|
21
|
+
return env.requires?.db?.kind === 'postgres' || readProject().dependencies?.['@cap-js/postgres']
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
async run() {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const cds = require('../../../cds')
|
|
2
|
-
const { fs: { promises: { rename } }, path: {
|
|
2
|
+
const { fs: { promises: { rename } }, path: { dirname, join }, exists } = cds.utils
|
|
3
3
|
const { readProject } = require('../../projectReader')
|
|
4
4
|
const { merge } = require('../../merge')
|
|
5
5
|
const { renderAndCopy } = require('../../template')
|
|
@@ -8,7 +8,7 @@ const TyperTemplate = require('../typer')
|
|
|
8
8
|
|
|
9
9
|
module.exports = class TypescriptTemplate extends require('../../plugin') {
|
|
10
10
|
static help() {
|
|
11
|
-
return '
|
|
11
|
+
return 'minimum configuration for a bare TypeScript project'
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
async canRun() {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const cds = require('../../../cds')
|
|
2
|
-
const { read, write } = cds.utils
|
|
2
|
+
const { read, write, exists } = cds.utils
|
|
3
3
|
const { readProject } = require('../../projectReader')
|
|
4
4
|
const { merge } = require('../../merge')
|
|
5
5
|
const { join } = require('path')
|
|
@@ -40,11 +40,20 @@ module.exports = class extends require('../../plugin') {
|
|
|
40
40
|
|
|
41
41
|
async combine() {
|
|
42
42
|
const project = readProject()
|
|
43
|
-
const { isJava, hasMta, srvPath, apps, appPath, appUIPaths, hasMultitenancy } = project
|
|
43
|
+
const { isJava, hasMta, srvPath, apps, appPath, appUIPaths, hasMultitenancy, strippedAppName } = project
|
|
44
44
|
|
|
45
|
-
await Promise.all(appUIPaths.map(p => {
|
|
45
|
+
await Promise.all(appUIPaths.map(async p => {
|
|
46
46
|
project.uiApp = p
|
|
47
|
-
|
|
47
|
+
const manifestPath = join(appPath, p, 'webapp/manifest.json')
|
|
48
|
+
const manifest = exists(manifestPath) ? await read(manifestPath) : {}
|
|
49
|
+
if (!manifest['sap.app']?.crossNavigation?.inbounds) {
|
|
50
|
+
return merge(__dirname, 'files/manifest.json.hbs').into(join(appPath, p, 'webapp/manifest.json'), { project })
|
|
51
|
+
} else {
|
|
52
|
+
return merge({ 'sap.cloud': {
|
|
53
|
+
public: true,
|
|
54
|
+
service: `${strippedAppName}.service`
|
|
55
|
+
}}).into(join(appPath, p, 'webapp/manifest.json'), { project })
|
|
56
|
+
}
|
|
48
57
|
}))
|
|
49
58
|
|
|
50
59
|
await Promise.all(apps.map(async ({ app }) => {
|
|
@@ -24,3 +24,11 @@ resources:
|
|
|
24
24
|
config:
|
|
25
25
|
xsappname: {{appName}}-${org}-${space}
|
|
26
26
|
tenant-mode: {{#hasMultitenancy}}shared{{/hasMultitenancy}}{{^hasMultitenancy}}dedicated{{/hasMultitenancy}}
|
|
27
|
+
{{#hasRoles}}
|
|
28
|
+
role-collections:
|
|
29
|
+
{{#roles}}
|
|
30
|
+
- name: '{{name}} ({{appName}} ${org}-${space})'
|
|
31
|
+
description: 'generated'
|
|
32
|
+
role-template-references: ['$XSAPPNAME.{{name}}']
|
|
33
|
+
{{/roles}}
|
|
34
|
+
{{/hasRoles}}
|
|
@@ -63,6 +63,17 @@ module.exports = class XsuaaTemplate extends require('../../plugin') {
|
|
|
63
63
|
into: [mtxSidecar, 'requires', 'name']
|
|
64
64
|
})
|
|
65
65
|
if (plan) project.servicePlan = plan
|
|
66
|
+
|
|
67
|
+
project.hasRoles = xsSecurity['role-templates'].length > 0
|
|
68
|
+
project.roles = xsSecurity['role-templates'].map(role => role)
|
|
69
|
+
|
|
70
|
+
for (const role of xsSecurity['role-templates']) {
|
|
71
|
+
additions.push({
|
|
72
|
+
in: [xsuaa, 'parameters.role-collections'],
|
|
73
|
+
where: { 'role-template-references': ['XSAPPNAME'+role.name] }
|
|
74
|
+
})
|
|
75
|
+
}
|
|
76
|
+
|
|
66
77
|
await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', { project, additions, overwrites, relationships })
|
|
67
78
|
}
|
|
68
79
|
|
package/lib/init/template.js
CHANGED
|
@@ -1,34 +1,46 @@
|
|
|
1
1
|
const Mustache = require('mustache')
|
|
2
2
|
const cds = require('../cds')
|
|
3
|
-
const { copy, read, write, exists, readdir, path, isdir } = cds.utils
|
|
4
|
-
|
|
5
|
-
async function renderAndCopy(from, into, replacements, overwrite = cds.cli.options.force) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
3
|
+
const { copy, read, write, exists, readdir, path, isdir, mkdirp } = cds.utils
|
|
4
|
+
|
|
5
|
+
async function renderAndCopy(from, into = '.', replacements = {}, overwrite = cds.cli.options.force) {
|
|
6
|
+
const srcRoot = path.resolve(from)
|
|
7
|
+
const destRoot = path.resolve(cds.root, into)
|
|
8
|
+
|
|
9
|
+
async function walk(src, dest) {
|
|
10
|
+
if (isdir(src)) {
|
|
11
|
+
await mkdirp(dest)
|
|
12
|
+
const entries = await readdir(src)
|
|
13
|
+
return Promise.all(entries.map(name => {
|
|
14
|
+
const renderedName = Mustache.render(name, replacements)
|
|
15
|
+
return walk(path.join(src, name), path.join(dest, renderedName))
|
|
16
|
+
}))
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const extension = path.extname(src)
|
|
20
|
+
|
|
21
|
+
if (extension === '.hbs') {
|
|
22
|
+
const destFile = dest.replace(/\.hbs$/, '')
|
|
23
|
+
if (overwrite || !exists(destFile)) {
|
|
24
|
+
const content = await render(src, replacements)
|
|
25
|
+
await write(destFile, content, { spaces: 2 })
|
|
26
|
+
}
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (overwrite || !exists(dest)) {
|
|
31
|
+
await copy(src, dest)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return walk(srcRoot, destRoot)
|
|
24
36
|
}
|
|
25
37
|
|
|
26
|
-
async function render(
|
|
27
|
-
|
|
28
|
-
|
|
38
|
+
async function render(templatePath, values = {}) {
|
|
39
|
+
const content = await read(templatePath, 'utf-8')
|
|
40
|
+
return Mustache.render(content, values)
|
|
29
41
|
}
|
|
30
42
|
|
|
31
43
|
module.exports = {
|
|
32
|
-
|
|
33
|
-
|
|
44
|
+
render,
|
|
45
|
+
renderAndCopy
|
|
34
46
|
}
|
package/lib/lint/eslintHelp.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "9.
|
|
2
|
+
"version": "9.32.0",
|
|
3
3
|
"help": "\n# SYNOPSIS\n\n *cds lint* [options] file.js [file.js] [dir]\n\n Runs environment checks and/or checks the specified models\n based on the ESLint framework\n\n# OPTIONS\n \n Basic configuration:\n --no-config-lookup Disable look up for eslint.config.js\n -c, --config path::String Use this configuration instead of eslint.config.js, eslint.config.mjs, or eslint.config.cjs\n --inspect-config Open the config inspector with the current configuration\n --ext [String] Specify additional file extensions to lint\n --global [String] Define global variables\n --parser String Specify the parser to be used\n --parser-options Object Specify parser options\n \n Specify Rules and Plugins:\n --plugin [String] Specify plugins\n --rule Object Specify rules\n \n Fix Problems:\n --fix Automatically fix problems\n --fix-dry-run Automatically fix problems without saving the changes to the file system\n --fix-type Array Specify the types of fixes to apply (directive, problem, suggestion, layout)\n \n Ignore Files:\n --no-ignore Disable use of ignore files and patterns\n --ignore-pattern [String] Patterns of files to ignore\n \n Use stdin:\n --stdin Lint code provided on <STDIN> - default: false\n --stdin-filename String Specify filename to process STDIN as\n \n Handle Warnings:\n --quiet Report errors only - default: false\n --max-warnings Int Number of warnings to trigger nonzero exit code - default: -1\n \n Output:\n -o, --output-file path::String Specify file to write report to\n -f, --format String Use a specific output format - default: stylish\n --color, --no-color Force enabling/disabling of color\n \n Inline configuration comments:\n --no-inline-config Prevent comments from changing config or rules\n --report-unused-disable-directives Adds reported errors for unused eslint-disable and eslint-enable directives\n --report-unused-disable-directives-severity String Chooses severity level for reporting unused eslint-disable and eslint-enable directives - either: off, warn, error, 0, 1, or 2\n --report-unused-inline-configs String Adds reported errors for unused eslint inline config comments - either: off, warn, error, 0, 1, or 2\n \n Caching:\n --cache Only check changed files - default: false\n --cache-file path::String Path to the cache file. Deprecated: use --cache-location - default: .eslintcache\n --cache-location path::String Path to the cache file or directory\n --cache-strategy String Strategy to use for detecting changed files in the cache - either: metadata or content - default: metadata\n \n Suppressing Violations:\n --suppress-all Suppress all violations - default: false\n --suppress-rule [String] Suppress specific rules\n --suppressions-location path::String Specify the location of the suppressions file\n --prune-suppressions Prune unused suppressions - default: false\n --pass-on-unpruned-suppressions Ignore unused suppressions - default: false\n \n Miscellaneous:\n --init Run config initialization wizard - default: false\n --env-info Output execution environment information - default: false\n --no-error-on-unmatched-pattern Prevent errors when pattern is unmatched\n --exit-on-fatal-error Exit with exit code 2 in case of fatal error - default: false\n --no-warn-ignored Suppress warnings when the file list includes ignored files\n --pass-on-no-patterns Exit with exit code 0 in case no file patterns are passed\n --debug Output debugging information\n -h, --help Show help\n -v, --version Output the version number\n --print-config path::String Print the configuration for the given file\n --stats Add statistics to the lint report - default: false\n --flag [String] Enable a feature flag\n --mcp Start the ESLint MCP server\n \n",
|
|
4
4
|
"options": [
|
|
5
5
|
"--config",
|