@sap/cds-dk 9.3.2 → 9.4.2
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 +59 -0
- package/bin/bind.js +1 -1
- package/bin/cds.js +3 -0
- package/bin/compile/index.js +53 -3
- package/bin/data-products/get-csn-via-dp-cli.js +41 -0
- package/bin/data-products/get-csn.js +76 -0
- package/bin/data-products/import.js +114 -0
- package/bin/data-products/index.js +30 -0
- package/bin/data-products/merge-csns.js +46 -0
- package/bin/data-products/prepare-csn.js +282 -0
- package/bin/data-products/prepare-files.js +69 -0
- package/bin/export.js +240 -0
- package/bin/help/export.md +37 -0
- package/bin/help/import.md +11 -0
- package/bin/help/minify.md +23 -0
- package/bin/import.js +13 -3
- package/bin/inspect.js +226 -0
- package/bin/minify.js +123 -0
- package/bin/up.js +2 -2
- package/bin/util/cli.js +132 -0
- package/bin/util/log.js +2 -0
- package/bin/version.js +2 -1
- package/bin/watch.js +21 -3
- package/lib/bind/shared.js +3 -1
- package/lib/build/buildTaskEngine.js +2 -1
- package/lib/build/plugins/helm/files/templates/NOTES.txt +1 -1
- package/lib/build/plugins/helm/index.js +1 -2
- package/lib/build/provider/internalBuildTaskProvider.js +3 -3
- package/lib/build/provider/nodejs/index.js +62 -3
- package/lib/deploy/index.js +1 -1
- package/lib/deploy/to-hana/hana.js +18 -16
- package/lib/import/odata/v2parser.js +2 -2
- package/lib/import/odata/v4parser.js +21 -2
- package/lib/import/odata.package.json +4 -4
- package/lib/init/constants.js +4 -1
- package/lib/init/index.js +6 -5
- package/lib/init/mvn.js +3 -2
- package/lib/init/projectReader.js +65 -55
- package/lib/init/registries/mta.js +6 -0
- package/lib/init/template/ams/files/manifest.yml.hbs +1 -1
- package/lib/init/template/ams/files/mta.yaml.hbs +1 -1
- package/lib/init/template/ams/index.js +7 -6
- package/lib/init/template/app-frontend/files/app-package.json.hbs +20 -0
- package/lib/init/template/app-frontend/files/index.html.hbs +34 -0
- package/lib/init/template/app-frontend/files/manifest.json +13 -0
- package/lib/init/template/app-frontend/files/mta.yaml.hbs +64 -0
- package/lib/init/template/app-frontend/files/package.json.hbs +17 -0
- package/lib/init/template/app-frontend/files/ui5-deploy.yaml.hbs +25 -0
- package/lib/init/template/app-frontend/files/ui5.yaml.hbs +6 -0
- package/lib/init/template/app-frontend/files/values.yaml.hbs +20 -0
- package/lib/init/template/app-frontend/files/xs-app.json.hbs +17 -0
- package/lib/init/template/app-frontend/index.js +98 -0
- package/lib/init/template/application-logging/index.js +13 -10
- package/lib/init/template/approuter/files/mta.yaml.hbs +0 -2
- package/lib/init/template/approuter/index.js +15 -9
- package/lib/init/template/attachments/index.js +7 -13
- package/lib/init/template/audit-logging/files/package.json.hbs +5 -0
- package/lib/init/template/audit-logging/index.js +4 -4
- package/lib/init/template/cloud-logging/index.js +13 -10
- package/lib/init/template/connectivity/index.js +3 -3
- package/lib/init/template/destination/index.js +6 -6
- package/lib/init/template/dynatrace/index.js +13 -10
- package/lib/init/template/enterprise-messaging/index.js +5 -5
- package/lib/init/template/enterprise-messaging-shared/index.js +4 -4
- package/lib/init/template/extensibility/index.js +2 -2
- package/lib/init/template/file-based-messaging/index.js +2 -2
- package/lib/init/template/github-actions/index.js +3 -3
- package/lib/init/template/hana/index.js +19 -22
- package/lib/init/template/handler/index.js +1 -0
- package/lib/init/template/helm/index.js +34 -21
- package/lib/init/template/html5-repo/files/containerize.yaml.hbs +0 -1
- package/lib/init/template/html5-repo/files/mta.yaml.hbs +10 -2
- package/lib/init/template/html5-repo/index.js +8 -6
- package/lib/init/template/http/index.js +31 -10
- package/lib/init/template/ias/files/manifest.yml.hbs +1 -1
- package/lib/init/template/ias/files/mta.yaml.hbs +9 -5
- package/lib/init/template/ias/files/values.yaml.hbs +14 -2
- package/lib/init/template/ias/index.js +8 -8
- package/lib/init/template/kafka/index.js +3 -3
- package/lib/init/template/local-messaging/index.js +2 -2
- package/lib/init/template/malware-scanner/index.js +3 -7
- package/lib/init/template/mta/files/mta.yaml.hbs +10 -0
- package/lib/init/template/multitenancy/files/mta.yaml.hbs +16 -3
- package/lib/init/template/multitenancy/files/package.json.hbs +5 -0
- package/lib/init/template/multitenancy/files/values.yaml.hbs +1 -6
- package/lib/init/template/multitenancy/index.js +8 -10
- package/lib/init/template/notifications/index.js +2 -2
- package/lib/init/template/portal/files/mta.yaml.hbs +18 -2
- package/lib/init/template/portal/index.js +7 -7
- package/lib/init/template/postgres/index.js +4 -4
- package/lib/init/template/redis/index.js +2 -2
- package/lib/init/template/redis-messaging/index.js +2 -2
- package/lib/init/template/sample/files/app/admin-books/fiori-service.cds +2 -2
- package/lib/init/template/sample/files/db/schema.cds +5 -8
- package/lib/init/template/sample/files/javascript/admin-service.js.hbs +24 -0
- package/lib/init/template/sample/files/javascript/cat-service.js.hbs +43 -0
- package/lib/init/template/sample/files/typescript/admin-service.ts.hbs +16 -0
- package/lib/init/template/sample/files/typescript/cat-service.ts.hbs +31 -0
- package/lib/init/template/test/files/test/test.xs.hbs +1 -1
- package/lib/init/template/test/index.js +2 -2
- package/lib/init/template/tiny-sample/index.js +1 -1
- package/lib/init/template/typer/files/xsconfig.json +2 -1
- package/lib/init/template/typescript/files/package.json +1 -1
- package/lib/init/template/typescript/files/tsconfig.json +4 -1
- package/lib/init/template/workzone-standard/files/mta.yaml.hbs +4 -0
- package/lib/init/template/workzone-standard/index.js +8 -8
- package/lib/init/template/xsuaa/files/mta.yaml.hbs +0 -2
- package/lib/init/template/xsuaa/files/package.json.hbs +3 -0
- package/lib/init/template/xsuaa/index.js +23 -18
- package/lib/lint/eslintHelp.json +1 -1
- package/lib/util/term.js +2 -4
- package/npm-shrinkwrap.json +28 -28
- package/package.json +1 -1
|
@@ -39,6 +39,19 @@ modules:
|
|
|
39
39
|
routes:
|
|
40
40
|
- route: "${default-url}"
|
|
41
41
|
- route: "${default-host}.cert.${default-domain}"{{/hasIas}}
|
|
42
|
+
{{#isNodejs}}
|
|
43
|
+
hooks:
|
|
44
|
+
- name: upgrade-all
|
|
45
|
+
type: task
|
|
46
|
+
phases:
|
|
47
|
+
- blue-green.application.before-start.idle
|
|
48
|
+
- deploy.application.before-start
|
|
49
|
+
parameters:
|
|
50
|
+
name: upgrade
|
|
51
|
+
memory: 512M # increase as required
|
|
52
|
+
disk-quota: 768M # increase as required
|
|
53
|
+
command: cds-mtx upgrade '*'
|
|
54
|
+
{{/isNodejs}}
|
|
42
55
|
provides:
|
|
43
56
|
- name: mtx-api
|
|
44
57
|
properties:
|
|
@@ -91,7 +104,7 @@ resources:
|
|
|
91
104
|
appName: {{appName}}-${org}-${space}
|
|
92
105
|
appCallbacks:
|
|
93
106
|
dependenciesCallbacks:
|
|
94
|
-
url: {{#isJava}}~{srv-api/srv-cert-url}/mt/sms/subscriptions/tenants/{app_tid}/dependencies{{/isJava}}{{#isNodejs}}~{mtx-api/mtx-cert-url}/-/cds/sms-provisioning/dependencies{{/isNodejs}}
|
|
107
|
+
url: {{#isJava}}~{srv-api/srv-cert-url}/mt/sms/subscriptions/tenants/{app_tid}/dependencies{{/isJava}}{{#isNodejs}}~{mtx-api/mtx-cert-url}/-/cds/sms-provisioning/dependencies/{app_tid}{{/isNodejs}}
|
|
95
108
|
subscriptionCallbacks:
|
|
96
109
|
url: {{#isJava}}~{srv-api/srv-cert-url}/mt/sms/subscriptions/tenants/{app_tid}{{/isJava}}{{#isNodejs}}~{mtx-api/mtx-cert-url}/-/cds/sms-provisioning/tenant/{app_tid}{{/isNodejs}}
|
|
97
110
|
async:
|
|
@@ -101,9 +114,9 @@ resources:
|
|
|
101
114
|
displayName: {{appName}}
|
|
102
115
|
description: Description for {{appName}}
|
|
103
116
|
category: Category
|
|
104
|
-
iasServiceInstanceName: {{appName}}-
|
|
117
|
+
iasServiceInstanceName: {{appName}}-ias{{#hasXsuaa}}
|
|
105
118
|
saasManagerServiceInstanceName: {{appName}}-registry{{/hasXsuaa}}
|
|
106
119
|
requires:
|
|
107
120
|
- name: {{#isJava}}srv-api{{/isJava}}{{^isJava}}mtx-api{{/isJava}}
|
|
108
|
-
processed-after: [{{#hasXsuaa}}{{appName}}-registry, {{/hasXsuaa}}{{appName}}-
|
|
121
|
+
processed-after: [{{#hasXsuaa}}{{appName}}-registry, {{/hasXsuaa}}{{appName}}-ias]
|
|
109
122
|
{{/hasIas}}
|
|
@@ -50,7 +50,7 @@ subscription-manager:
|
|
|
50
50
|
parameters:
|
|
51
51
|
appCallbacks:
|
|
52
52
|
dependenciesCallbacks:
|
|
53
|
-
{{#literal}}url: https://{{ .Release.Name }}-sidecar-{{ .Release.Namespace }}.cert.{{ .Values.global.domain }}/-/cds/sms-provisioning/dependencies{{/literal}}
|
|
53
|
+
{{#literal}}url: https://{{ .Release.Name }}-sidecar-{{ .Release.Namespace }}.cert.{{ .Values.global.domain }}/-/cds/sms-provisioning/dependencies/{app_tid}{{/literal}}
|
|
54
54
|
subscriptionCallbacks:
|
|
55
55
|
{{#literal}}url: https://{{ .Release.Name }}-sidecar-{{ .Release.Namespace }}.cert.{{ .Values.global.domain }}/-/cds/sms-provisioning/tenant/{app_tid}{{/literal}}
|
|
56
56
|
appName: {{appName}}
|
|
@@ -87,11 +87,6 @@ sidecar:
|
|
|
87
87
|
serviceInstanceName: service-manager
|
|
88
88
|
image:
|
|
89
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}}
|
|
95
90
|
resources:
|
|
96
91
|
limits:
|
|
97
92
|
ephemeral-storage: 1G
|
|
@@ -19,9 +19,7 @@ module.exports = class MultitenancyTemplate extends require('../../plugin') {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
static hasInProduction(env) {
|
|
22
|
-
|
|
23
|
-
// REVISIT: Check if this can be simplified
|
|
24
|
-
return options?.add?.has('mtx') || options?.add?.has('multitenancy') || !!env.requires?.multitenancy || false
|
|
22
|
+
return env.requires?.multitenancy
|
|
25
23
|
}
|
|
26
24
|
|
|
27
25
|
async run() {
|
|
@@ -44,12 +42,12 @@ module.exports = class MultitenancyTemplate extends require('../../plugin') {
|
|
|
44
42
|
async combine() {
|
|
45
43
|
const project = readProject()
|
|
46
44
|
const {
|
|
47
|
-
isNodejs, isJava,
|
|
48
|
-
hasXsuaa, hasIas, hasHana,
|
|
45
|
+
isNodejs, isJava, addMta, addHelm, addHelmUnifiedRuntime,
|
|
46
|
+
addXsuaa, hasXsuaa, addIas, hasIas, hasHana, addContainerize, hasApprouter,
|
|
49
47
|
srvPath, appName
|
|
50
48
|
} = project
|
|
51
49
|
|
|
52
|
-
if (
|
|
50
|
+
if (addMta || addIas || addXsuaa) {
|
|
53
51
|
const srv = srv4(srvPath)
|
|
54
52
|
const mtxSidecar = mtxSidecar4(isJava ? 'mtx/sidecar' : 'gen/mtx/sidecar')
|
|
55
53
|
const modules = [srv, mtxSidecar]
|
|
@@ -60,7 +58,7 @@ module.exports = class MultitenancyTemplate extends require('../../plugin') {
|
|
|
60
58
|
if (isJava) apis.push(requiredMtxSidecarApi4(srv))
|
|
61
59
|
const additions = [...modules, ...services, ...apis]
|
|
62
60
|
const relationships = []
|
|
63
|
-
if (
|
|
61
|
+
if (addXsuaa) {
|
|
64
62
|
relationships.push({
|
|
65
63
|
insert: [saasRegistry, 'name'],
|
|
66
64
|
into: [isJava ? srv : mtxSidecar, 'requires', 'name']
|
|
@@ -82,7 +80,7 @@ module.exports = class MultitenancyTemplate extends require('../../plugin') {
|
|
|
82
80
|
await merge(templateMtaPath).into('mta.yaml', { with: project, additions, relationships })
|
|
83
81
|
}
|
|
84
82
|
|
|
85
|
-
if (
|
|
83
|
+
if (addHelm || addHelmUnifiedRuntime) {
|
|
86
84
|
await merge(__dirname, 'files/values.yaml.hbs').into('chart/values.yaml', { with: project })
|
|
87
85
|
const applicationWorkload = hasApprouter ? 'approuter' : 'srv'
|
|
88
86
|
await merge({
|
|
@@ -96,7 +94,7 @@ module.exports = class MultitenancyTemplate extends require('../../plugin') {
|
|
|
96
94
|
}).into('chart/values.yaml',{ forceOverwrite: true })
|
|
97
95
|
}
|
|
98
96
|
|
|
99
|
-
if (
|
|
97
|
+
if (addContainerize) {
|
|
100
98
|
const deletions = []
|
|
101
99
|
if (hasHana) {
|
|
102
100
|
deletions.push({
|
|
@@ -113,7 +111,7 @@ module.exports = class MultitenancyTemplate extends require('../../plugin') {
|
|
|
113
111
|
await merge(__dirname, '/files/containerize.yaml.hbs').into('containerize.yaml', { with: project, additions, deletions })
|
|
114
112
|
}
|
|
115
113
|
|
|
116
|
-
if (
|
|
114
|
+
if (addXsuaa) {
|
|
117
115
|
await merge(__dirname, 'files/xs-security.json.hbs').into('xs-security.json', {
|
|
118
116
|
project,
|
|
119
117
|
additions: [{
|
|
@@ -35,9 +35,9 @@ module.exports = class NotificationsTemplate extends require('../../plugin') {
|
|
|
35
35
|
|
|
36
36
|
async combine() {
|
|
37
37
|
const project = readProject()
|
|
38
|
-
const {
|
|
38
|
+
const { addMta } = project
|
|
39
39
|
|
|
40
|
-
if (
|
|
40
|
+
if (addMta) {
|
|
41
41
|
await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', { project, additions: [notificationTypesDeployer] })
|
|
42
42
|
}
|
|
43
43
|
}
|
|
@@ -37,11 +37,16 @@ modules:
|
|
|
37
37
|
name: {{appName}}-portal-key
|
|
38
38
|
config:
|
|
39
39
|
content-endpoint: developer
|
|
40
|
-
|
|
40
|
+
{{#hasXsuaa}}
|
|
41
|
+
- name: {{appName}}-auth
|
|
42
|
+
{{/hasXsuaa}}
|
|
43
|
+
{{#hasIas}}
|
|
44
|
+
- name: {{appName}}-ias
|
|
41
45
|
parameters:
|
|
42
46
|
config:
|
|
43
47
|
credential-type: X509_GENERATED
|
|
44
|
-
app-identifier: portal-deployer
|
|
48
|
+
app-identifier: portal-deployer
|
|
49
|
+
{{/hasIas}}
|
|
45
50
|
- name: {{appName}}-html5-repo-host
|
|
46
51
|
- name: {{appName}}-app-deployer
|
|
47
52
|
deployed-after:
|
|
@@ -63,3 +68,14 @@ resources:
|
|
|
63
68
|
type: org.cloudfoundry.managed-service
|
|
64
69
|
parameters:
|
|
65
70
|
service: destination
|
|
71
|
+
|
|
72
|
+
- name: {{appName}}-ias
|
|
73
|
+
type: org.cloudfoundry.managed-service
|
|
74
|
+
parameters:
|
|
75
|
+
service: identity
|
|
76
|
+
|
|
77
|
+
- name: {{appName}}-html5-repo-host
|
|
78
|
+
type: org.cloudfoundry.managed-service
|
|
79
|
+
parameters:
|
|
80
|
+
service: html5-apps-repo
|
|
81
|
+
service-plan: app-host
|
|
@@ -28,13 +28,13 @@ module.exports = class PortalTemplate extends require('../../plugin') {
|
|
|
28
28
|
|
|
29
29
|
async combine() {
|
|
30
30
|
const project = readProject()
|
|
31
|
-
const { appName, isJava, hasMta, srvPath,
|
|
31
|
+
const { appName, isJava, addMta, hasMta, srvPath, addHtml5Repo, addXsuaa, addApprouter, addMultitenancy, addHelm, addHelmUnifiedRuntime, addContainerize, hasApprouter, hasHtml5Repo } = project
|
|
32
32
|
|
|
33
|
-
if (
|
|
33
|
+
if (addMultitenancy) {
|
|
34
34
|
await merge(__dirname, 'files/package.sidecar.json').into('mtx/sidecar/package.json')
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
if (hasMta) {
|
|
37
|
+
if (addMta || (addXsuaa || addHtml5Repo || addApprouter || addMultitenancy) && hasMta) {
|
|
38
38
|
const srv = srv4(srvPath)
|
|
39
39
|
const additions = [srv, portal, appDeployer, portalDeployer]
|
|
40
40
|
const relationships = [{
|
|
@@ -45,7 +45,7 @@ module.exports = class PortalTemplate extends require('../../plugin') {
|
|
|
45
45
|
into: [portalDeployer, 'requires', 'name']
|
|
46
46
|
}]
|
|
47
47
|
|
|
48
|
-
if (
|
|
48
|
+
if (addXsuaa) {
|
|
49
49
|
additions.push(xsuaa)
|
|
50
50
|
relationships.push({
|
|
51
51
|
insert: [xsuaa, 'name'],
|
|
@@ -68,7 +68,7 @@ module.exports = class PortalTemplate extends require('../../plugin') {
|
|
|
68
68
|
})
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
if (
|
|
71
|
+
if (addMultitenancy) {
|
|
72
72
|
relationships.push({
|
|
73
73
|
insert: [portal, 'name'],
|
|
74
74
|
into: [isJava ? srv : mtxSidecar4('gen/mtx/sidecar'), 'requires', 'name']
|
|
@@ -80,7 +80,7 @@ module.exports = class PortalTemplate extends require('../../plugin') {
|
|
|
80
80
|
})
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
if (
|
|
83
|
+
if (addContainerize) {
|
|
84
84
|
const additions = [{
|
|
85
85
|
in: 'modules',
|
|
86
86
|
where: { name: `${appName}-portal-deployer` }
|
|
@@ -88,7 +88,7 @@ module.exports = class PortalTemplate extends require('../../plugin') {
|
|
|
88
88
|
await merge(__dirname, '/files/containerize.yaml.hbs').into('containerize.yaml', { with: project, additions })
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
if (
|
|
91
|
+
if (addHelm || addHelmUnifiedRuntime) {
|
|
92
92
|
await merge(__dirname, 'files/values.yaml.hbs').into('chart/values.yaml', { with: project })
|
|
93
93
|
}
|
|
94
94
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const cds = require('../../../cds')
|
|
2
|
-
const { read } = cds.utils
|
|
2
|
+
const { read, exists } = cds.utils
|
|
3
3
|
const { readProject } = require('../../projectReader')
|
|
4
4
|
const { merge } = require('../../merge')
|
|
5
5
|
const mvn = require('../../mvn')
|
|
@@ -24,16 +24,16 @@ module.exports = class PostgresTemplate extends require('../../plugin') {
|
|
|
24
24
|
async run() {
|
|
25
25
|
const project = readProject()
|
|
26
26
|
const { configFile, isJava } = project
|
|
27
|
-
project.shortcut = typeof (await read(configFile)).cds?.requires?.db !== 'object'
|
|
27
|
+
project.shortcut = !exists(configFile) || typeof (await read(configFile)).cds?.requires?.db !== 'object'
|
|
28
28
|
await merge(__dirname, 'files/package.json.hbs').into('package.json', { project })
|
|
29
29
|
if (isJava) await mvn.add('postgresql')
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
async combine() {
|
|
33
33
|
const project = readProject()
|
|
34
|
-
const {
|
|
34
|
+
const { addMta, srvPath } = project
|
|
35
35
|
|
|
36
|
-
if (
|
|
36
|
+
if (addMta) {
|
|
37
37
|
const srv = srv4(srvPath)
|
|
38
38
|
await merge(__dirname, 'files/mta.yml.hbs').into('mta.yaml', {
|
|
39
39
|
project,
|
|
@@ -27,9 +27,9 @@ module.exports = class extends require('../../plugin') {
|
|
|
27
27
|
|
|
28
28
|
async combine() {
|
|
29
29
|
const project = readProject()
|
|
30
|
-
const {
|
|
30
|
+
const { addMta, srvPath } = project
|
|
31
31
|
|
|
32
|
-
if (
|
|
32
|
+
if (addMta) {
|
|
33
33
|
const srv = srv4(srvPath)
|
|
34
34
|
await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', {
|
|
35
35
|
project,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const cds = require('../../../cds')
|
|
2
|
-
const { read } = cds.utils
|
|
2
|
+
const { read, exists } = cds.utils
|
|
3
3
|
const { readProject } = require('../../projectReader')
|
|
4
4
|
const { merge } = require('../../merge')
|
|
5
5
|
|
|
@@ -28,7 +28,7 @@ module.exports = class RedisMessagingTemplate extends require('../../plugin') {
|
|
|
28
28
|
async run() {
|
|
29
29
|
const project = readProject()
|
|
30
30
|
const { configFile } = project
|
|
31
|
-
project.shortcut = typeof (await read(configFile)).cds?.requires?.messaging !== 'object'
|
|
31
|
+
project.shortcut = !exists(configFile) || typeof (await read(configFile)).cds?.requires?.messaging !== 'object'
|
|
32
32
|
await merge(__dirname, 'files/package.json.hbs').into(configFile, { project })
|
|
33
33
|
}
|
|
34
34
|
}
|
|
@@ -109,8 +109,8 @@ extend service AdminService {
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
// Workaround for Fiori popups for asking user to enter a valid UUID on Create
|
|
112
|
-
annotate AdminService.Authors : ID with @Core.Computed
|
|
113
|
-
annotate AdminService.Books : ID with @Core.Computed
|
|
112
|
+
annotate AdminService.Authors : ID with @Core.Computed;
|
|
113
|
+
annotate AdminService.Books : ID with @Core.Computed;
|
|
114
114
|
|
|
115
115
|
// Show Genre as drop down, not a dialog
|
|
116
116
|
annotate AdminService.Books with {
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
using {
|
|
2
|
-
Currency,
|
|
3
|
-
managed,
|
|
4
|
-
cuid,
|
|
5
|
-
sap
|
|
6
|
-
} from '@sap/cds/common';
|
|
1
|
+
using { Currency, managed, sap } from '@sap/cds/common';
|
|
7
2
|
|
|
8
3
|
namespace sap.capire.bookshop;
|
|
9
4
|
|
|
10
|
-
entity Books : managed
|
|
5
|
+
entity Books : managed {
|
|
6
|
+
key ID : Integer;
|
|
11
7
|
title : localized String(111) @mandatory;
|
|
12
8
|
descr : localized String(1111);
|
|
13
9
|
author : Association to Authors @mandatory;
|
|
@@ -17,7 +13,8 @@ entity Books : managed, cuid {
|
|
|
17
13
|
currency : Currency;
|
|
18
14
|
}
|
|
19
15
|
|
|
20
|
-
entity Authors : managed
|
|
16
|
+
entity Authors : managed {
|
|
17
|
+
key ID : Integer;
|
|
21
18
|
name : String(111) @mandatory;
|
|
22
19
|
dateOfBirth : Date;
|
|
23
20
|
dateOfDeath : Date;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{{#isESM}}
|
|
2
|
+
import cds from '@sap/cds'
|
|
3
|
+
|
|
4
|
+
export class AdminService extends cds.ApplicationService { init() {
|
|
5
|
+
{{/isESM}}
|
|
6
|
+
{{^isESM}}
|
|
7
|
+
const cds = require('@sap/cds')
|
|
8
|
+
|
|
9
|
+
module.exports = class AdminService extends cds.ApplicationService { init() {
|
|
10
|
+
{{/isESM}}
|
|
11
|
+
|
|
12
|
+
const { Books } = this.entities
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Generate IDs for new Books drafts
|
|
16
|
+
*/
|
|
17
|
+
this.before ('NEW', Books.drafts, async (req) => {
|
|
18
|
+
if (req.data.ID) return
|
|
19
|
+
const { ID:id1 } = await SELECT.one.from(Books).columns('max(ID) as ID')
|
|
20
|
+
const { ID:id2 } = await SELECT.one.from(Books.drafts).columns('max(ID) as ID')
|
|
21
|
+
req.data.ID = Math.max(id1||0, id2||0) + 1
|
|
22
|
+
})
|
|
23
|
+
return super.init()
|
|
24
|
+
}}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{{#isESM}}
|
|
2
|
+
import cds from '@sap/cds'
|
|
3
|
+
|
|
4
|
+
export class CatalogService extends cds.ApplicationService { init() {
|
|
5
|
+
{{/isESM}}
|
|
6
|
+
{{^isESM}}
|
|
7
|
+
const cds = require('@sap/cds')
|
|
8
|
+
|
|
9
|
+
module.exports = class CatalogService extends cds.ApplicationService { init() {
|
|
10
|
+
{{/isESM}}
|
|
11
|
+
|
|
12
|
+
const { Books } = cds.entities('sap.capire.bookshop')
|
|
13
|
+
const { ListOfBooks } = this.entities
|
|
14
|
+
|
|
15
|
+
// Add some discount for overstocked books
|
|
16
|
+
this.after('each', ListOfBooks, book => {
|
|
17
|
+
if (book.stock > 111) book.title += ` -- 11% discount!`
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
// Reduce stock of ordered books if available stock suffices
|
|
21
|
+
this.on('submitOrder', async req => {
|
|
22
|
+
let { book:id, quantity } = req.data
|
|
23
|
+
let book = await SELECT.one.from (Books, id, b => b.stock)
|
|
24
|
+
|
|
25
|
+
// Validate input data
|
|
26
|
+
if (!book) return req.error (404, `Book #${id} doesn't exist`)
|
|
27
|
+
if (quantity < 1) return req.error (400, `quantity has to be 1 or more`)
|
|
28
|
+
if (!book.stock || quantity > book.stock) return req.error (409, `${quantity} exceeds stock for book #${id}`)
|
|
29
|
+
|
|
30
|
+
// Reduce stock in database and return updated stock value
|
|
31
|
+
await UPDATE (Books, id) .with ({ stock: book.stock -= quantity })
|
|
32
|
+
return book
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
// Emit event when an order has been submitted
|
|
36
|
+
this.after('submitOrder', async (_,req) => {
|
|
37
|
+
let { book, quantity } = req.data
|
|
38
|
+
await this.emit('OrderedBook', { book, quantity, buyer: req.user.id })
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
// Delegate requests to the underlying generic service
|
|
42
|
+
return super.init()
|
|
43
|
+
}}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import cds from '@sap/cds'
|
|
2
|
+
|
|
3
|
+
import { Authors, Books } from '#cds-models/AdminService'
|
|
4
|
+
|
|
5
|
+
export class AdminService extends cds.ApplicationService { init(){
|
|
6
|
+
this.before (['NEW','CREATE'], Authors, genid)
|
|
7
|
+
this.before (['NEW','CREATE'], Books, genid)
|
|
8
|
+
return super.init()
|
|
9
|
+
}}
|
|
10
|
+
|
|
11
|
+
/** Generate primary keys for target entity in request */
|
|
12
|
+
async function genid (req:any) {
|
|
13
|
+
if (req.data.ID) return
|
|
14
|
+
const {id} = await SELECT.one.from(req.target).columns('max(ID) as id')
|
|
15
|
+
req.data.ID = id + 4 // Note: that is not safe! ok for this sample only.
|
|
16
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import cds from '@sap/cds'
|
|
2
|
+
|
|
3
|
+
import { Books } from '#cds-models/sap/capire/bookshop'
|
|
4
|
+
import { submitOrder, ListOfBooks } from '#cds-models/CatalogService'
|
|
5
|
+
|
|
6
|
+
export class CatalogService extends cds.ApplicationService { async init() {
|
|
7
|
+
|
|
8
|
+
// Add some discount for overstocked books
|
|
9
|
+
this.after('each', ListOfBooks, book => {
|
|
10
|
+
if (book?.stock === undefined || book.stock === null) return
|
|
11
|
+
if (book?.stock > 111) book.title += ` -- 11% discount!`
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
// Reduce stock of ordered books if available stock suffices
|
|
15
|
+
this.on(submitOrder, async req => {
|
|
16
|
+
let { book:id, quantity } = req.data
|
|
17
|
+
let book = await SELECT.from (Books, id!, b => b.stock)
|
|
18
|
+
|
|
19
|
+
// Validate input data
|
|
20
|
+
if (!book) return req.error (404, `Book #${id} doesn't exist`)
|
|
21
|
+
if (!quantity || quantity < 1) return req.error (400, `quantity has to be 1 or more`)
|
|
22
|
+
if (quantity > book.stock!) return req.error (409, `${quantity} exceeds stock for book #${id}`)
|
|
23
|
+
|
|
24
|
+
// Reduce stock in database and return updated stock value
|
|
25
|
+
await UPDATE (Books, id) .with ({ stock: book.stock! -= quantity })
|
|
26
|
+
return book
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
// Delegate requests to the underlying generic service
|
|
30
|
+
return super.init()
|
|
31
|
+
}}
|
|
@@ -13,7 +13,7 @@ const { GET, POST, expect, axios } = cds.test (__dirname+'/..')
|
|
|
13
13
|
axios.defaults.auth = { username: '{{user}}', password: '{{password}}' }
|
|
14
14
|
{{/user}}
|
|
15
15
|
|
|
16
|
-
describe('OData APIs', () => {
|
|
16
|
+
describe('{{serviceName}} OData APIs', () => {
|
|
17
17
|
|
|
18
18
|
{{#entities}}{{=<% %>=}}
|
|
19
19
|
it('serves <%name%>', async () => {
|
|
@@ -69,7 +69,7 @@ async function createNodeTest(proj) {
|
|
|
69
69
|
.filter(([name]) => name.match(nameFilter))
|
|
70
70
|
.filter(([name]) => !name.match(/[._]texts$/))
|
|
71
71
|
.filter(([, e]) => !e['@cds.autoexposed']) // only consider non-autoexposed entities to reduce clutter
|
|
72
|
-
.map(([, e]) => e)
|
|
72
|
+
.map(([name, e]) => {e._nameUnqualified = name; return e})
|
|
73
73
|
|
|
74
74
|
let entity // use one entity only (don't want to make users test all entities)
|
|
75
75
|
if (entities.length) entity = entities[0]
|
|
@@ -99,7 +99,7 @@ async function createNodeTest(proj) {
|
|
|
99
99
|
|
|
100
100
|
proj.entities = [{
|
|
101
101
|
name: entity.name,
|
|
102
|
-
urlPath: `/${sInfo.endpoints[0].path}${entity.
|
|
102
|
+
urlPath: `/${sInfo.endpoints[0].path}${entity._nameUnqualified}`,
|
|
103
103
|
selectString: selectElements.join(','),
|
|
104
104
|
elementsString: JSON.stringify(
|
|
105
105
|
Object.entries(sampleData[entity.name][0])
|
|
@@ -14,7 +14,7 @@ module.exports = class TinySampleTemplate extends require('../../plugin') {
|
|
|
14
14
|
async run() {
|
|
15
15
|
const { isJava } = readProject()
|
|
16
16
|
if (isJava) {
|
|
17
|
-
if (!cds.cli.options.add
|
|
17
|
+
if (!cds.cli.options.add?.has(JAVA)) {
|
|
18
18
|
await mvn.add('tiny_sample')
|
|
19
19
|
}
|
|
20
20
|
} else {
|
|
@@ -11,10 +11,12 @@ modules:
|
|
|
11
11
|
- name: {{appName}}-destinations
|
|
12
12
|
type: com.sap.application.content
|
|
13
13
|
requires:
|
|
14
|
+
{{#hasXsuaa}}
|
|
14
15
|
- name: {{appName}}-auth
|
|
15
16
|
parameters:
|
|
16
17
|
service-key:
|
|
17
18
|
name: {{appName}}-auth-key
|
|
19
|
+
{{/hasXsuaa}}
|
|
18
20
|
- name: {{appName}}-html5-repo-host
|
|
19
21
|
parameters:
|
|
20
22
|
service-key:
|
|
@@ -34,11 +36,13 @@ modules:
|
|
|
34
36
|
ServiceInstanceName: {{appName}}-html5-repo-host
|
|
35
37
|
ServiceKeyName: {{appName}}-html5-repo-host-key
|
|
36
38
|
sap.cloud.service: {{strippedAppName}}.service
|
|
39
|
+
{{#hasXsuaa}}
|
|
37
40
|
- Name: {{appName}}-auth
|
|
38
41
|
Authentication: OAuth2UserTokenExchange
|
|
39
42
|
ServiceInstanceName: {{appName}}-auth
|
|
40
43
|
ServiceKeyName: {{appName}}-auth-key
|
|
41
44
|
sap.cloud.service: {{strippedAppName}}.service
|
|
45
|
+
{{/hasXsuaa}}
|
|
42
46
|
|
|
43
47
|
- name: {{appName}}-mtx
|
|
44
48
|
type: nodejs
|
|
@@ -26,21 +26,22 @@ module.exports = class extends require('../../plugin') {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
static hasInProduction(env) {
|
|
29
|
-
return !!env.requires?.workzone || cds.cli.options.add
|
|
29
|
+
return !!env.requires?.workzone || cds.cli.options.add?.has('workzone-standard')
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
async run() {
|
|
33
|
-
|
|
33
|
+
const project = readProject()
|
|
34
|
+
const conf = project.isJava ? { requires: { workzone: true }} : { cds: { requires: { workzone: true } } }
|
|
35
|
+
await merge(conf).into(project.configFile)
|
|
34
36
|
|
|
35
37
|
if (cds.cli.options.cdm) {
|
|
36
|
-
const project = readProject()
|
|
37
38
|
await merge(join(__dirname, 'files/cdm.json.hbs')).into('app/workzone/cdm.json', { project })
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
async combine() {
|
|
42
43
|
const project = readProject()
|
|
43
|
-
const { isJava, hasMta, srvPath, apps, appPath, appUIPaths,
|
|
44
|
+
const { isJava, addMta, hasMta, srvPath, apps, appPath, appUIPaths, addMultitenancy, strippedAppName } = project
|
|
44
45
|
|
|
45
46
|
await Promise.all(appUIPaths.map(async p => {
|
|
46
47
|
project.uiApp = p
|
|
@@ -66,7 +67,7 @@ module.exports = class extends require('../../plugin') {
|
|
|
66
67
|
await merge(__dirname, 'files/xs-app.json.hbs').into(join(appPath, app, 'xs-app.json'), { with: project, additions, overwrites })
|
|
67
68
|
}))
|
|
68
69
|
|
|
69
|
-
if (
|
|
70
|
+
if (addMultitenancy) {
|
|
70
71
|
const mtxPackageJson = await read('mtx/sidecar/package.json')
|
|
71
72
|
mtxPackageJson.cds ??= {}
|
|
72
73
|
mtxPackageJson.cds.requires ??= {}
|
|
@@ -77,14 +78,14 @@ module.exports = class extends require('../../plugin') {
|
|
|
77
78
|
await write('mtx/sidecar/package.json', mtxPackageJson, { spaces: 2 })
|
|
78
79
|
}
|
|
79
80
|
|
|
80
|
-
if (hasMta) {
|
|
81
|
+
if (addMta || addMultitenancy && hasMta) {
|
|
81
82
|
const srv = srv4(srvPath)
|
|
82
83
|
const additions = [srv, destinations, destination, {
|
|
83
84
|
in: [destination, 'requires'],
|
|
84
85
|
where: { name: 'srv-api' }
|
|
85
86
|
}]
|
|
86
87
|
const relationships = []
|
|
87
|
-
if (
|
|
88
|
+
if (addMultitenancy) {
|
|
88
89
|
additions.push(html5RepoHost)
|
|
89
90
|
relationships.push({
|
|
90
91
|
insert: [html5RepoHost, 'name'],
|
|
@@ -92,7 +93,6 @@ module.exports = class extends require('../../plugin') {
|
|
|
92
93
|
})
|
|
93
94
|
}
|
|
94
95
|
|
|
95
|
-
|
|
96
96
|
await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', { with: project, additions, relationships })
|
|
97
97
|
}
|
|
98
98
|
}
|
|
@@ -6,13 +6,11 @@ modules:
|
|
|
6
6
|
requires:
|
|
7
7
|
- name: {{appName}}-auth
|
|
8
8
|
|
|
9
|
-
{{#hasMultitenancy}}
|
|
10
9
|
- name: {{appName}}-mtx
|
|
11
10
|
type: nodejs
|
|
12
11
|
path: {{#isNodejs}}gen/{{/isNodejs}}mtx/sidecar
|
|
13
12
|
requires:
|
|
14
13
|
- name: {{appName}}-auth
|
|
15
|
-
{{/hasMultitenancy}}
|
|
16
14
|
|
|
17
15
|
resources:
|
|
18
16
|
- name: {{appName}}-auth{{#servicePlan}}-{{servicePlan}}{{/servicePlan}}
|