@sap/cds-dk 8.0.2 → 8.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/CHANGELOG.md +49 -3
  2. package/bin/bind.js +3 -3
  3. package/bin/cds.js +8 -7
  4. package/bin/init.js +3 -6
  5. package/bin/version.js +5 -3
  6. package/bin/watch.js +12 -4
  7. package/lib/build/constants.js +1 -0
  8. package/lib/build/provider/hana/index.js +54 -37
  9. package/lib/build/provider/internalBuildTaskProvider.js +2 -2
  10. package/lib/build/provider/mtx-sidecar/index.js +10 -3
  11. package/lib/build/provider/nodejs/index.js +4 -3
  12. package/lib/compile/to-mermaid.js +27 -12
  13. package/lib/deploy/to-hana/hana.js +10 -8
  14. package/lib/deploy/to-hana/hdiDeployUtil.js +9 -1
  15. package/lib/init/constants.js +13 -3
  16. package/lib/init/index.js +6 -4
  17. package/lib/init/projectReader.js +3 -4
  18. package/lib/init/template/audit-logging/files/package.sidecar.json +7 -0
  19. package/lib/init/template/audit-logging/index.js +1 -1
  20. package/lib/init/template/cf-manifest/index.js +4 -0
  21. package/lib/init/template/cov2ap/files/dependencies.package.json +5 -0
  22. package/lib/init/template/cov2ap/index.js +31 -0
  23. package/lib/init/template/data/as-json.js +25 -11
  24. package/lib/init/template/destination/files/mta.yaml.hbs +6 -0
  25. package/lib/init/template/destination/files/package.sidecar.json +7 -0
  26. package/lib/init/template/destination/index.js +12 -2
  27. package/lib/init/template/event-queue/files/dependencies.package.json +5 -0
  28. package/lib/init/template/event-queue/index.js +35 -0
  29. package/lib/init/template/html5-repo/files/mta.yaml.hbs +6 -58
  30. package/lib/init/template/html5-repo/files/package.sidecar.json +7 -0
  31. package/lib/init/template/html5-repo/files/xs-app.json.hbs +1 -15
  32. package/lib/init/template/html5-repo/index.js +13 -10
  33. package/lib/init/template/http/index.js +37 -28
  34. package/lib/init/template/malware-scanner/index.js +1 -1
  35. package/lib/init/template/mta/files/package.json +1 -1
  36. package/lib/init/template/redis/files/mta.yaml.hbs +25 -0
  37. package/lib/init/template/redis/files/package.json.hbs +5 -0
  38. package/lib/init/template/redis/index.js +44 -0
  39. package/lib/init/template/redis-messaging/files/package.json.hbs +0 -3
  40. package/lib/init/template/redis-messaging/index.js +4 -18
  41. package/lib/init/template/sample/files/app/admin-books/webapp/manifest.json +0 -1
  42. package/lib/init/template/sample/files/app/browse/webapp/manifest.json +0 -1
  43. package/lib/init/template/sample/files/nodejs/admin-service.js +13 -8
  44. package/lib/init/template/sample/files/nodejs/cat-service.js +27 -15
  45. package/lib/init/template/typescript/files/package.json +3 -3
  46. package/lib/init/template/websocket/files/dependencies.package.json +5 -0
  47. package/lib/init/template/websocket/index.js +35 -0
  48. package/lib/init/template/workzone/index.js +1 -0
  49. package/lib/init/template/workzone-standard/files/mta.yaml.hbs +59 -0
  50. package/lib/init/template/workzone-standard/index.js +24 -8
  51. package/npm-shrinkwrap.json +22 -19
  52. package/package.json +1 -1
  53. package/lib/init/template/redis-messaging/files/mta.yaml.hbs +0 -14
@@ -149,6 +149,7 @@ module.exports = class HttpTemplate extends require('../../plugin') {
149
149
  }
150
150
  varsDefined = true
151
151
  const headers = auth ? `Content-Type: application/json\n{{auth}}` : `Content-Type: application/json`
152
+ const headerAuth = auth ? '{{auth}}' : ''
152
153
 
153
154
  service.urlPaths.forEach((urlPath) => {
154
155
  if (service.urlPaths.length > 1) {
@@ -156,36 +157,41 @@ module.exports = class HttpTemplate extends require('../../plugin') {
156
157
  }
157
158
 
158
159
  service.entities.forEach((e) => {
159
- const entityNameSimple = e.name.slice(e.name.lastIndexOf('.') + 1)
160
+ const entityNameSimple = e.name.slice(serviceName.length + 1)
161
+ const nameSlug = slug(entityNameSimple)
160
162
  const url = `{{server}}/${urlPath}${entityNameSimple}`
161
- const requestTitle = `\n### ${e.name}`
162
- requests.push(`${requestTitle}\nGET ${url}\n${headers}\n`)
163
+ const requestTitle = `\n### ${entityNameSimple}`
164
+ requests.push(`${requestTitle}\n# @name ${nameSlug}_GET\nGET ${url}\n${headerAuth}\n`)
163
165
  if (e.readOnly) return
164
166
 
165
167
  const entityData = payload[`${e.name}`] ? payload[`${e.name}`][0] : null
166
168
  if (!entityData) return
167
- const postBody = JSON.stringify(entityData, null, 2)
168
-
169
- let id
170
- const compositeKey = Object.keys(e.keys).length > 1
171
- if (compositeKey) {
172
- id = e.keys.map(k => k.type === 'cds.String' ? `${k.name}='${entityData[k.name]}'` : `${k.name}=${entityData[k.name]}`).join(',')
173
- } else {
174
- id = entityData[Object.keys(e.keys)[0]]
175
- }
176
169
 
177
170
  if (e.isDraft) {
178
- generateDraftRequests(requests, requestTitle, url, headers, postBody, id)
179
- } else {
171
+ const key = Object.keys(e.keys)[0] // draft keys are always single
172
+ delete entityData[key] // draft keys should always by auto generated (either UUID or through custom logic), so remove them from the payload
173
+ const postBody = JSON.stringify(entityData, null, 2)
174
+ generateDraftRequests(requests, requestTitle, url, headers, headerAuth, postBody, key)
175
+ }
176
+ else {
177
+ const postBody = JSON.stringify(entityData, null, 2)
178
+ let id
179
+ const compositeKey = Object.keys(e.keys).length > 1
180
+ if (compositeKey) {
181
+ id = e.keys.map(k => k.type === 'cds.String' ? `${k.name}='${entityData[k.name]}'` : `${k.name}=${entityData[k.name]}`).join(',')
182
+ } else {
183
+ id = entityData[Object.keys(e.keys)[0]]
184
+ }
180
185
  compositeKey ? id = `(${id})` : id = `/${id}`
181
- requests.push(`${requestTitle}\nPOST ${url}\n${headers}\n\n${postBody}\n`)
182
- requests.push(`${requestTitle}\nPATCH ${url}${id}\n${headers}\n\n${postBody}\n`)
183
- requests.push(`${requestTitle}\nDELETE ${url}${id}\n${headers}\n`)
186
+ requests.push(`${requestTitle}\n# @name ${nameSlug}_POST\nPOST ${url}\n${headers}\n\n${postBody}\n`)
187
+ requests.push(`${requestTitle}\n# @name ${nameSlug}_PATCH\nPATCH ${url}${id}\n${headers}\n\n${postBody}\n`)
188
+ requests.push(`${requestTitle}\n# @name ${nameSlug}_DELETE\nDELETE ${url}${id}\n${headers}\n`)
184
189
  }
185
190
  })
186
191
 
187
192
  service.actions.forEach((a) => {
188
- const url = `{{server}}/${urlPath}${a.name.split(".")[1]}`
193
+ const simpleNameAction = a.name.slice(serviceName.length + 1)
194
+ const url = `{{server}}/${urlPath}${simpleNameAction}`
189
195
 
190
196
  let actionPayload = {}
191
197
  if (a.params) {
@@ -197,20 +203,25 @@ module.exports = class HttpTemplate extends require('../../plugin') {
197
203
  : null
198
204
  }
199
205
  }
200
- requests.push(`\n### ${a.name}\nPOST ${url}\n${headers}\n\n${JSON.stringify(actionPayload, null, 2)}\n`)
206
+ requests.push(`\n### ${simpleNameAction}\n# @name ${simpleNameAction}_POST\nPOST ${url}\n${headers}\n\n${JSON.stringify(actionPayload, null, 2)}\n`)
201
207
  })
202
208
 
203
209
  })
204
210
  this.#write(requests, serviceName)
205
211
  }
206
212
 
207
- function generateDraftRequests(requests, requestTitle, url, headers, postBody, id) {
208
- requests.push(`${requestTitle} Drafts \nGET ${url}?$filter=(IsActiveEntity eq false)\n${headers}\n`) // unencoded URL for better readability (client can handle this)
209
- requests.push(`${requestTitle} Drafts \nPOST ${url}\n${headers}\n\n${postBody}\n`)
210
- requests.push(`\n### Please paste the server-generated draft id here e.g. ID=101 or ID=101,secodKey='stringValue' \n@draftID = ${id}\n`)
211
- requests.push(`${requestTitle} Patch Draft \nPATCH ${url}({{draftID}},IsActiveEntity=false)\n${headers}\n\n${postBody}\n`)
212
- requests.push(`${requestTitle} Prepare Draft \nPOST ${url}({{draftID}},IsActiveEntity=false)/AdminService.draftPrepare\n${headers}\n\n{}\n`)
213
- requests.push(`${requestTitle} Activate Draft \nPOST ${url}({{draftID}},IsActiveEntity=false)/AdminService.draftActivate\n${headers}\n\n{}\n`)
213
+ function generateDraftRequests(requests, title, url, headers, headerAuth, postBody, key) {
214
+ const nameDraftsCreate = slug(title+'_Draft_POST')
215
+ 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)
216
+ requests.push(`${title} Draft POST\n# @name ${nameDraftsCreate}\nPOST ${url}\n${headers}\n\n${postBody}\n`)
217
+ requests.push(`\n### Result from POST request above\n@draftID = {{${nameDraftsCreate}.response.body.$.${key}}}\n`)
218
+ requests.push(`${title} Draft PATCH\n# @name ${slug(title+'_Draft_Patch')}\nPATCH ${url}(${key}={{draftID}},IsActiveEntity=false)\n${headers}\n\n${postBody}\n`)
219
+ requests.push(`${title} Draft Prepare\n# @name ${slug(title+'_Draft_Prepare')}\nPOST ${url}(${key}={{draftID}},IsActiveEntity=false)/AdminService.draftPrepare\n${headers}\n\n{}\n`)
220
+ requests.push(`${title} Draft Activate\n# @name ${slug(title+'_Draft_Activate')}\nPOST ${url}(${key}={{draftID}},IsActiveEntity=false)/AdminService.draftActivate\n${headers}\n\n{}\n`)
221
+ }
222
+
223
+ function slug(str) {
224
+ return str.trim().replace(/[#\\. ]/g, '')
214
225
  }
215
226
  }
216
227
 
@@ -248,5 +259,3 @@ module.exports = class HttpTemplate extends require('../../plugin') {
248
259
  return `${outputDir}/${serviceName}.http`
249
260
  }
250
261
  }
251
-
252
-
@@ -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 Malware Scanning Service'
9
9
  }
10
10
 
11
11
  static hasInProduction(env) {
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "devDependencies": {
3
- "@sap/cds-dk": ">=7"
3
+ "@sap/cds-dk": "^8"
4
4
  }
5
5
  }
@@ -0,0 +1,25 @@
1
+ ---
2
+ modules:
3
+ - name: {{appName}}-srv
4
+ type: {{language}}
5
+ path: {{& srvPath}}
6
+ requires:
7
+ - name: {{appName}}-redis
8
+
9
+ resources:
10
+ - name: {{appName}}-redis
11
+ type: org.cloudfoundry.managed-service
12
+ parameters:
13
+ service: redis-cache
14
+ service-plan: standard
15
+ # config:
16
+ # memory: 2 # GB, can be 2 or 4
17
+ # multi_az: true
18
+ # cluster_mode: true
19
+ # shard_count: 1
20
+ # node_count: 3 # per shard minimum is 3 (for standard plan)
21
+ # engine_version: "6.0" # can be "4.0" or "6.0"
22
+ # maintenance_window:
23
+ # day_of_week: Friday
24
+ # start_hour_utc: 0
25
+ # duration: 5 # hours
@@ -0,0 +1,5 @@
1
+ {
2
+ "dependencies": {
3
+ "redis": "^4"
4
+ }
5
+ }
@@ -0,0 +1,44 @@
1
+ const { readProject } = require('../../projectReader')
2
+ const { merge } = require('../../merge')
3
+ const { srv4, redis } = require('../../registries/mta')
4
+
5
+ module.exports = class extends require('../../plugin') {
6
+
7
+ static help() {
8
+ return 'SAP BTP Redis, Hyperscaler Option'
9
+ }
10
+
11
+ async canRun() {
12
+ const { hasMta, hasHelm, hasHelmUnifiedRuntime, isJava } = readProject()
13
+ const onlyHelm = !hasMta && (hasHelmUnifiedRuntime || hasHelm)
14
+ if (isJava) throw `'cds add redis' is not available for Java yet`
15
+ if (onlyHelm) throw `'cds add redis' is not available for Kyma yet`
16
+ return true
17
+ }
18
+
19
+ static hasInProduction() {
20
+ const { dependencies } = readProject()
21
+ return !!dependencies?.['redis']
22
+ }
23
+
24
+ async run() {
25
+ await merge(__dirname, 'files/package.json.hbs').into('package.json')
26
+ }
27
+
28
+ async combine() {
29
+ const project = readProject()
30
+ const { hasMta, srvPath } = project
31
+
32
+ if (hasMta) {
33
+ const srv = srv4(srvPath)
34
+ await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', {
35
+ project,
36
+ additions: [srv, redis],
37
+ relationships: [{
38
+ insert: [redis, 'name'],
39
+ into: [srv, 'requires', 'name']
40
+ }]
41
+ })
42
+ }
43
+ }
44
+ }
@@ -1,8 +1,5 @@
1
1
  {
2
2
  {{#isNodejs}}
3
- "dependencies": {
4
- "redis": "^4"
5
- },
6
3
  "cds": {
7
4
  {{/isNodejs}}
8
5
  "requires": {
@@ -2,7 +2,6 @@ const cds = require('../../../cds')
2
2
  const { read } = cds.utils
3
3
  const { readProject } = require('../../projectReader')
4
4
  const { merge } = require('../../merge')
5
- const { srv4, redis } = require('../../registries/mta')
6
5
 
7
6
  module.exports = class RedisMessagingTemplate extends require('../../plugin') {
8
7
 
@@ -10,6 +9,10 @@ module.exports = class RedisMessagingTemplate extends require('../../plugin') {
10
9
  return 'messaging via Redis'
11
10
  }
12
11
 
12
+ requires() {
13
+ return ['redis']
14
+ }
15
+
13
16
  async canRun() {
14
17
  const { hasMta, hasHelm, hasHelmUnifiedRuntime, isJava } = readProject()
15
18
  const onlyHelm = !hasMta && (hasHelmUnifiedRuntime || hasHelm)
@@ -28,21 +31,4 @@ module.exports = class RedisMessagingTemplate extends require('../../plugin') {
28
31
  project.shortcut = !(await read(configFile)).cds?.requires?.messaging?.kind
29
32
  await merge(__dirname, 'files/package.json.hbs').into(configFile, { project })
30
33
  }
31
-
32
- async combine() {
33
- const project = readProject()
34
- const { hasMta, srvPath } = project
35
-
36
- if (hasMta) {
37
- const srv = srv4(srvPath)
38
- await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', {
39
- project,
40
- additions: [srv, redis],
41
- relationships: [{
42
- insert: [redis, 'name'],
43
- into: [srv, 'requires', 'name']
44
- }]
45
- })
46
- }
47
- }
48
34
  }
@@ -55,7 +55,6 @@
55
55
  "": {
56
56
  "dataSource": "AdminService",
57
57
  "settings": {
58
- "synchronizationMode": "None",
59
58
  "operationMode": "Server",
60
59
  "autoExpandSelect": true,
61
60
  "earlyRequests": true,
@@ -71,7 +71,6 @@
71
71
  "": {
72
72
  "dataSource": "CatalogService",
73
73
  "settings": {
74
- "synchronizationMode": "None",
75
74
  "operationMode": "Server",
76
75
  "autoExpandSelect": true,
77
76
  "earlyRequests": true,
@@ -1,12 +1,17 @@
1
- const cds = require('@sap/cds/lib')
1
+ const cds = require('@sap/cds')
2
2
 
3
3
  module.exports = class AdminService extends cds.ApplicationService { init(){
4
- this.before ('NEW','Books.drafts', genid)
4
+
5
+ const { Books } = this.entities
6
+
7
+ /**
8
+ * Generate IDs for new Books drafts
9
+ */
10
+ this.before ('NEW', Books.drafts, async (req) => {
11
+ if (req.data.ID) return
12
+ const { ID:id1 } = await SELECT.one.from(Books).columns('max(ID) as ID')
13
+ const { ID:id2 } = await SELECT.one.from(Books.drafts).columns('max(ID) as ID')
14
+ req.data.ID = Math.max(id1||0, id2||0) + 1
15
+ })
5
16
  return super.init()
6
17
  }}
7
-
8
- /** Generate primary keys for target entity in request */
9
- async function genid (req) {
10
- const {ID} = await cds.tx(req).run (SELECT.one.from(req.target.actives).columns('max(ID) as ID'))
11
- req.data.ID = ID - ID % 100 + 100 + 1
12
- }
@@ -1,26 +1,38 @@
1
1
  const cds = require('@sap/cds')
2
- const { Books } = cds.entities ('sap.capire.bookshop')
3
2
 
4
- class CatalogService extends cds.ApplicationService { init(){
3
+ class CatalogService extends cds.ApplicationService { init() {
5
4
 
6
- // Reduce stock of ordered books if available stock suffices
7
- this.on ('submitOrder', async req => {
8
- const {book,quantity} = req.data
9
- let {stock} = await SELECT `stock` .from (Books,book)
10
- if (stock >= quantity) {
11
- await UPDATE (Books,book) .with (`stock -=`, quantity)
12
- await this.emit ('OrderedBook', { book, quantity, buyer:req.user.id })
13
- return { stock }
14
- }
15
- else return req.error (409,`${quantity} exceeds stock for book #${book}`)
16
- })
5
+ const { Books } = cds.entities('sap.capire.bookshop')
6
+ const { ListOfBooks } = this.entities
17
7
 
18
8
  // Add some discount for overstocked books
19
- this.after ('each','ListOfBooks', book => {
9
+ this.after('each', ListOfBooks, book => {
20
10
  if (book.stock > 111) book.title += ` -- 11% discount!`
21
11
  })
22
12
 
13
+ // Reduce stock of ordered books if available stock suffices
14
+ this.on('submitOrder', async req => {
15
+ let { book:id, quantity } = req.data
16
+ let book = await SELECT.from (Books, id, b => b.stock)
17
+
18
+ // Validate input data
19
+ if (!book) return req.error (404, `Book #${id} doesn't exist`)
20
+ if (quantity < 1) return req.error (400, `quantity has to be 1 or more`)
21
+ if (quantity > book.stock) return req.error (409, `${quantity} exceeds stock for book #${id}`)
22
+
23
+ // Reduce stock in database and return updated stock value
24
+ await UPDATE (Books, id) .with ({ stock: book.stock -= quantity })
25
+ return book
26
+ })
27
+
28
+ // Emit event when an order has been submitted
29
+ this.after('submitOrder', async (_,req) => {
30
+ let { book, quantity } = req.data
31
+ await this.emit('OrderedBook', { book, quantity, buyer: req.user.id })
32
+ })
33
+
34
+ // Delegate requests to the underlying generic service
23
35
  return super.init()
24
36
  }}
25
37
 
26
- module.exports = { CatalogService }
38
+ module.exports = CatalogService
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "devDependencies": {
3
- "typescript": "^5",
4
- "@cap-js/cds-types": "<1",
5
- "@types/node": "^20"
3
+ "@cap-js/cds-types": "^0.6",
4
+ "@types/node": "^20",
5
+ "typescript": "^5"
6
6
  },
7
7
  "scripts": {
8
8
  "watch": "cds-ts w",
@@ -0,0 +1,5 @@
1
+ {
2
+ "dependencies": {
3
+ "@cap-js-community/websocket": "^1"
4
+ }
5
+ }
@@ -0,0 +1,35 @@
1
+ const { readProject } = require('../../projectReader')
2
+ const { merge, sort } = require('../../merge')
3
+ const { link } = require('../../../util/term')
4
+ const { CAP_JS_COMMUNITY_WEBSOCKET } = require('../../constants').URLS
5
+
6
+ module.exports = class WebsocketTemplate extends require('../../plugin') {
7
+
8
+ static help() {
9
+ return 'cap-js-community: expose CDS services via the Websocket protocol'
10
+ }
11
+
12
+ async canRun() {
13
+ const { isJava } = readProject()
14
+ if (isJava) throw `'cds add websocket' is not available for Java`
15
+ return true
16
+ }
17
+
18
+ requires() {
19
+ return ['redis']
20
+ }
21
+
22
+ static hasInProduction() {
23
+ const { dependencies } = readProject()
24
+ return !!dependencies?.['@cap-js-community/websocket']
25
+ }
26
+
27
+ async run() {
28
+ await merge(__dirname, 'files/dependencies.package.json').into('package.json')
29
+ await sort('package.json', 'dependencies')
30
+ }
31
+
32
+ async finalize() {
33
+ console.log(`Find plugin documentation on ${link(CAP_JS_COMMUNITY_WEBSOCKET)}`)
34
+ }
35
+ }
@@ -1,4 +1,5 @@
1
1
  module.exports = class extends require('../../plugin') {
2
+
2
3
  requires() {
3
4
  return ['workzone-standard']
4
5
  }
@@ -0,0 +1,59 @@
1
+ ---
2
+ modules:
3
+ - name: {{appName}}-destinations
4
+ type: com.sap.application.content
5
+ requires:
6
+ - name: {{appName}}-auth
7
+ parameters:
8
+ service-key:
9
+ name: {{appName}}-auth-key
10
+ - name: {{appName}}-html5-repo-host
11
+ parameters:
12
+ service-key:
13
+ name: {{appName}}-html5-repo-host-key
14
+ - name: srv-api
15
+ - name: {{appName}}-destination
16
+ parameters:
17
+ content-target: true
18
+ build-parameters:
19
+ no-source: true
20
+ parameters:
21
+ content:
22
+ instance:
23
+ existing_destinations_policy: update
24
+ destinations:
25
+ - Name: {{appName}}-html5-repository
26
+ ServiceInstanceName: {{appName}}-html5-repo-host
27
+ ServiceKeyName: {{appName}}-html5-repo-host-key
28
+ sap.cloud.service: {{appName}}.service
29
+ - Name: {{appName}}-auth
30
+ Authentication: OAuth2UserTokenExchange
31
+ ServiceInstanceName: {{appName}}-auth
32
+ ServiceKeyName: {{appName}}-auth-key
33
+ sap.cloud.service: {{appName}}.service
34
+
35
+ - name: {{appName}}-destination
36
+ type: org.cloudfoundry.managed-service
37
+ parameters:
38
+ service: destination
39
+ service-plan: lite
40
+ config:
41
+ HTML5Runtime_enabled: true
42
+ init_data:
43
+ instance:
44
+ existing_destinations_policy: update
45
+ destinations:
46
+ - Name: {{appName}}-srv-api
47
+ URL: ~{srv-api/srv-url}
48
+ Authentication: NoAuthentication
49
+ Type: HTTP
50
+ ProxyType: Internet
51
+ HTML5.ForwardAuthToken: true
52
+ HTML5.DynamicDestination: true
53
+ requires:
54
+ - name: srv-api
55
+ group: destinations
56
+ properties:
57
+ name: srv-api # must be used in xs-app.json as well
58
+ url: ~{srv-url}
59
+ forwardAuthToken: true
@@ -2,22 +2,27 @@ const cds = require('../../../cds')
2
2
  const { readProject } = require('../../projectReader')
3
3
  const { merge } = require('../../merge')
4
4
  const { join } = require('path')
5
+ const { destination, destinations } = require('../../registries/mta')
5
6
 
6
7
  module.exports = class extends require('../../plugin') {
7
8
 
8
- canRun() {
9
- if (cds.requires.multitenancy) {
10
- throw `SAP BTP Work Zone, Standard Edition does not support multitenancy yet.`
11
- }
12
- return true
9
+ static help() {
10
+ return 'SAP BTP Work Zone, Standard Edition'
13
11
  }
14
12
 
15
13
  requires() {
16
- return ['html5-repo']
14
+ return ['html5-repo', 'destination']
17
15
  }
18
16
 
19
- static help() {
20
- return 'SAP BTP Work Zone, Standard Edition'
17
+ static hasInProduction(env) {
18
+ return !!env.requires?.workzone
19
+ }
20
+
21
+ canRun() {
22
+ if (cds.requires.multitenancy) {
23
+ throw `SAP BTP Work Zone, Standard Edition does not support multitenancy yet.`
24
+ }
25
+ return true
21
26
  }
22
27
 
23
28
  async run() {
@@ -26,5 +31,16 @@ module.exports = class extends require('../../plugin') {
26
31
  await Promise.all(appUIPaths.map(p =>
27
32
  merge(__dirname, 'files/manifest.json.hbs').into(join(appPath, p, 'webapp/manifest.json'), { project })
28
33
  ))
34
+ await merge({ cds: { requires: { workzone: true } } }).into('package.json')
29
35
  }
36
+
37
+ async combine() {
38
+ const project = readProject()
39
+ const { hasMta } = project
40
+
41
+ if (hasMta) {
42
+ const additions = [destinations, destination]
43
+ await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', { with: project, additions })
44
+ }
45
+ }
30
46
  }