@sap/cds-dk 4.8.2 → 4.9.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.
Files changed (83) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/bin/activate.js +8 -7
  3. package/bin/bind.js +12 -12
  4. package/bin/build/all.js +3 -5
  5. package/bin/build/index.js +1 -1
  6. package/bin/cds.js +1 -1
  7. package/bin/deploy/index.js +7 -1
  8. package/bin/deploy/to-hana.js +5 -4
  9. package/bin/deploy/to-sqlite.js +2 -1
  10. package/bin/extend.js +5 -5
  11. package/bin/help.js +1 -0
  12. package/bin/import.js +45 -31
  13. package/bin/login.js +5 -6
  14. package/bin/logout.js +2 -2
  15. package/bin/parse.js +19 -0
  16. package/lib/bind/bindingUtil.js +41 -49
  17. package/lib/bind/cfKeyProvider.js +9 -17
  18. package/lib/bind/userCdsrcJsonStorageProvider.js +1 -0
  19. package/lib/client/activate.js +3 -2
  20. package/lib/client/extend.js +5 -6
  21. package/lib/client/helper/fs_helper.js +8 -8
  22. package/lib/client/settings_manager.js +12 -9
  23. package/lib/compile/openapi/csdl2openapi.js +213 -165
  24. package/lib/compile/openapi/index.js +1 -2
  25. package/lib/compile/to-xsuaa.js +1 -1
  26. package/lib/import/index.js +22 -15
  27. package/lib/import/message.js +3 -1
  28. package/lib/import/utils/MetadataConverter.js +1 -1
  29. package/lib/import/v2parser.js +112 -56
  30. package/lib/import/v4parser.js +149 -98
  31. package/lib/init/constants.js +6 -2
  32. package/lib/init/index.js +3 -2
  33. package/lib/init/template/_merging/existences.js +80 -4
  34. package/lib/init/template/approuter/files/cds.cdsrc.json +7 -0
  35. package/lib/init/template/approuter/files/cds.cdsrc.json.hbs +9 -0
  36. package/lib/init/template/approuter/files/cds.package.json +9 -0
  37. package/lib/init/template/approuter/files/cds.package.json.hbs +11 -0
  38. package/lib/init/template/approuter/files/index.html +1 -0
  39. package/lib/init/template/approuter/files/mta.yaml.hbs +35 -21
  40. package/lib/init/template/approuter/files/package.json +3 -0
  41. package/lib/init/template/approuter/files/xs-app.json.hbs +19 -0
  42. package/lib/init/template/approuter/index.js +47 -18
  43. package/lib/init/template/auditlog/index.js +5 -5
  44. package/lib/init/template/hana/files/java/cdsrc.json.hbs +7 -0
  45. package/lib/init/template/hana/files/java/{package.json → db/package.json} +0 -0
  46. package/lib/init/template/hana/files/java/profile.cdsrc.json.hbs +12 -0
  47. package/lib/init/template/hana/files/mta.yaml.hbs +10 -17
  48. package/lib/init/template/hana/files/nodejs/cds.package.json.hbs +9 -0
  49. package/lib/init/template/hana/files/nodejs/cds.profile.package.json.hbs +14 -0
  50. package/lib/init/template/hana/files/nodejs/dependencies.package.json +1 -1
  51. package/lib/init/template/hana/index.js +60 -86
  52. package/lib/init/template/java/index.js +5 -2
  53. package/lib/init/template/kibana-logging/files/cds.package.json +7 -0
  54. package/lib/init/template/kibana-logging/files/cds.profile.package.json.hbs +9 -0
  55. package/lib/init/template/kibana-logging/files/mta.yaml.hbs +13 -0
  56. package/lib/init/template/kibana-logging/index.js +64 -0
  57. package/lib/init/template/mta/files/mta.yaml.hbs +3 -8
  58. package/lib/init/template/mta/index.js +8 -2
  59. package/lib/init/template/mtx/files/cds.package.json +0 -12
  60. package/lib/init/template/mtx/files/cds.package.json.hbs +14 -0
  61. package/lib/init/template/mtx/files/java/.cdsrc.json +17 -0
  62. package/lib/init/template/mtx/files/java/package.json +43 -0
  63. package/lib/init/template/mtx/files/java/server.js +30 -0
  64. package/lib/init/template/mtx/files/mta.yaml.hbs +6 -6
  65. package/lib/init/template/mtx/index.js +41 -22
  66. package/lib/init/template/templateBase.js +4 -1
  67. package/lib/init/template/xsuaa/files/cds.cdsrc.json +7 -0
  68. package/lib/init/template/xsuaa/files/cds.cdsrc.json.hbs +9 -0
  69. package/lib/init/template/xsuaa/files/cds.package.json +1 -1
  70. package/lib/init/template/xsuaa/files/cds.package.json.hbs +11 -0
  71. package/lib/init/template/xsuaa/files/mta.yaml.hbs +2 -2
  72. package/lib/init/template/xsuaa/index.js +43 -27
  73. package/lib/init/types.d.ts +43 -19
  74. package/lib/init/util/fsUtil.js +15 -4
  75. package/lib/init/util/projectReader.js +21 -18
  76. package/lib/init/util/templateUtil.js +78 -28
  77. package/lib/util/exec.js +2 -2
  78. package/lib/watch/livereload-server.js +3 -0
  79. package/lib/watch/node-watch.js +8 -1
  80. package/npm-shrinkwrap.json +170 -148
  81. package/package.json +3 -3
  82. package/lib/init/template/approuter/files/xs-app.json +0 -8
  83. package/lib/init/template/nodejs/files/.vscode/settings.json +0 -7
@@ -0,0 +1,64 @@
1
+ const cds = require('@sap/cds')
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+
5
+ const ProjectReader = require('../../util/projectReader');
6
+
7
+ const TemplateBase = require('../templateBase');
8
+
9
+ const { PROJECT_TYPE, } = require('../../constants');
10
+ const { srvNode, srvJava, kibanaLogging } = require('../_merging/existences');
11
+
12
+ module.exports = class KibanaTemplate extends TemplateBase {
13
+ constructor(projectPath, generator) {
14
+ super(projectPath, generator, __dirname);
15
+ this.projectReader = new ProjectReader(this);
16
+ }
17
+
18
+ async runMTAMerging() {
19
+ const mtaYAMLPath = path.join(this.projectPath, 'mta.yaml');
20
+
21
+ if (!fs.existsSync(mtaYAMLPath)) {
22
+ console.warn(`Cannot add Kibana Logging as there is no 'mta.yaml' deploy descriptor in your project. Run 'cds add mta' to add it.`)
23
+ return;
24
+ }
25
+
26
+ const projectDescriptor = await this.projectReader.read(this.options);
27
+ const srv = projectDescriptor.cap.isNodejs ? srvNode : srvJava
28
+
29
+ await this.templateUtil.mergeYAML(
30
+ mtaYAMLPath,
31
+ `${__dirname}/files/mta.yaml.hbs`,
32
+ projectDescriptor,
33
+ {
34
+ existences: [srv, kibanaLogging],
35
+ relationships: [{
36
+ in: srv,
37
+ inKeyPath: ["requires"],
38
+ into: "name",
39
+ existences: [kibanaLogging],
40
+ existenceKeyPath: ["name"],
41
+ }],
42
+ }
43
+ );
44
+ }
45
+
46
+ async run() {
47
+ const projectType = await this.getProjectType();
48
+
49
+ switch (projectType) {
50
+ case PROJECT_TYPE.java:
51
+ default:
52
+ cds.error(`kibana-logging is not implemented for project type '${projectType}' yet`);
53
+ // TODO: implement
54
+ break;
55
+ case PROJECT_TYPE.nodejs: {
56
+ const projectDescriptor = await this.projectReader.read(this.options);
57
+ const cdsTemplateFile = projectDescriptor.cap.for ? 'cds.profile.package.json.hbs' : 'cds.package.json'
58
+ const cdsTemplatePath = path.join(__dirname, 'files', cdsTemplateFile)
59
+ await this.templateUtil.mergeJSON(path.join(this.projectPath, 'package.json'), cdsTemplatePath, projectDescriptor)
60
+ }
61
+ }
62
+ await this.runMTAMerging()
63
+ }
64
+ }
@@ -9,12 +9,6 @@ build-parameters:
9
9
  before-all:
10
10
  - builder: custom
11
11
  commands:
12
- {{#cap.isNodejs}}
13
- - npm ci
14
- {{/cap.isNodejs}}
15
- {{#cap.isJava}}
16
- - npm install --production
17
- {{/cap.isJava}}
18
12
  - npx -p @sap/cds-dk cds build --production
19
13
 
20
14
  modules:
@@ -34,8 +28,9 @@ modules:
34
28
  SPRING_PROFILES_ACTIVE: cloud
35
29
  build-parameters:
36
30
  builder: custom
37
- commands: [ mvn clean package ]
38
- build-result: "target/*-exec.[wj]ar"
31
+ commands:
32
+ - mvn clean package -DskipTests=true
33
+ build-result: target/*-exec.jar
39
34
  {{/cap.isJava}}
40
35
  provides:
41
36
  - name: srv-api # required by consumers of CAP services (e.g. approuter)
@@ -1,4 +1,5 @@
1
- const path = require('path');
1
+ const { existsSync } = require('fs');
2
+ const { join } = require('path');
2
3
  const TemplateBase = require('../templateBase');
3
4
  const ProjectReader = require('../../util/projectReader');
4
5
 
@@ -10,13 +11,18 @@ module.exports = class MtaTemplate extends TemplateBase {
10
11
 
11
12
  async run() {
12
13
  const projectDescriptor = await this.projectReader.read();
13
- if (!await this.fsUtil.pathExists(path.join(this.projectPath, 'mta.yaml'))) {
14
+ if (!existsSync(join(this.projectPath, 'mta.yaml'))) {
14
15
  await this.templateUtil.copyFiles('.', this.projectPath, projectDescriptor);
15
16
  }
16
17
 
17
18
  // Re-applying the merging part of `cds add xsuaa`, `cds add hana`, and `cds add mtx`, if necessary.
18
19
  // TODO: Find a generic solution for situation like these. Probably involves some restructuring in the
19
20
  // project reader, so that there's a logical mapping from hasX to XTemplate.
21
+ if (projectDescriptor.cap.hasApprouter) {
22
+ const ApprouterTemplate = require(`../approuter`)
23
+ const template = new ApprouterTemplate(this.projectPath, this.generator)
24
+ await template.runMTAMerging()
25
+ }
20
26
  if (projectDescriptor.cap.hasHana) {
21
27
  const HanaTemplate = require(`../hana`)
22
28
  const template = new HanaTemplate(this.projectPath, this.generator)
@@ -1,20 +1,8 @@
1
1
  {
2
2
  "cds": {
3
3
  "requires": {
4
- "auth": {
5
- "strategy": "JWT"
6
- },
7
- "db": {
8
- "kind": { "#overwrite": "hana" },
9
- "vcap": {
10
- "label": "service-manager"
11
- }
12
- },
13
4
  "multitenancy": true
14
5
  },
15
- "hana": {
16
- "deploy-format": "hdbtable"
17
- },
18
6
  "mtx": {
19
7
  "element-prefix": "Z_",
20
8
  "namespace-blocklist": [],
@@ -0,0 +1,14 @@
1
+ {
2
+ "cds": {
3
+ "requires": {
4
+ "[{{cap.for}}]": {
5
+ "multitenancy": true
6
+ }
7
+ },
8
+ "mtx": {
9
+ "element-prefix": "Z_",
10
+ "namespace-blocklist": [],
11
+ "extension-allowlist": []
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "build": {
3
+ "tasks": [
4
+ {
5
+ "for": "java-cf"
6
+ },
7
+ {
8
+ "for": "mtx",
9
+ "src": ".",
10
+ "dest": "mtx-sidecar"
11
+ },
12
+ {
13
+ "for": "hana"
14
+ }
15
+ ]
16
+ }
17
+ }
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "cap-mtx-sidecar",
3
+ "dependencies": {
4
+ "@sap/cds": "^5.4.3",
5
+ "@sap/cds-mtx": "^2.2.0",
6
+ "@sap/hdi-deploy": "^4.3.0",
7
+ "@sap/instance-manager": "^3.0.0",
8
+ "@sap/xssec": "^3",
9
+ "@sap/hana-client": "^2.8.16",
10
+ "express": "^4.17.1",
11
+ "passport": "^0.5.0"
12
+ },
13
+ "scripts": {
14
+ "start": "node server.js"
15
+ },
16
+ "engines": {
17
+ "node": ">=12.18"
18
+ },
19
+ "cds": {
20
+ "features": {
21
+ "kibana_formatter": true
22
+ },
23
+ "build": {
24
+ "tasks": [
25
+ {
26
+ "for": "hana"
27
+ },
28
+ {
29
+ "for": "java-cf"
30
+ }
31
+ ]
32
+ },
33
+ "requires": {
34
+ "auth": {
35
+ "kind": "xsuaa"
36
+ },
37
+ "db": {
38
+ "kind": "hana-mt"
39
+ },
40
+ "multitenancy": true
41
+ }
42
+ }
43
+ }
@@ -0,0 +1,30 @@
1
+ const app = require('express')();
2
+ const cds = require('@sap/cds');
3
+
4
+ const main = async () => {
5
+ app.use(defaults.correlate);
6
+
7
+ await cds.connect.to('db');
8
+ const PORT = process.env.PORT || 4004;
9
+ await cds.mtx.in(app);
10
+
11
+ app.listen(PORT);
12
+ }
13
+
14
+ const defaults = {
15
+ get correlate() {
16
+ return (req, _, next) => {
17
+ if (!cds.context) cds.context = {}
18
+ const id = cds.context.id
19
+ || req.headers['x-correlation-id'] || req.headers['x-correlationid']
20
+ || req.headers['x-request-id'] || req.headers['x-vcap-request-id']
21
+ || cds.utils.uuid()
22
+ cds.context.id = req.headers['x-correlation-id'] = id
23
+ if (!cds.context._) cds.context._ = {}
24
+ if (!cds.context._.req) cds.context._.req = req
25
+ next();
26
+ }
27
+ }
28
+ }
29
+
30
+ main();
@@ -11,7 +11,7 @@ modules:
11
11
  requires:
12
12
  - name: {{cap.appName}}-registry
13
13
  {{#cap.isJava}}
14
- - name: sidecar
14
+ - name: mtx-sidecar
15
15
  properties:
16
16
  CDS_MULTITENANCY_SIDECAR_URL: ~{url}
17
17
  {{/cap.isJava}}
@@ -33,10 +33,10 @@ modules:
33
33
  memory: 256M
34
34
  disk-quota: 512M
35
35
  requires:
36
- - name: bookshop-db
37
- - name: bookshop-uaa
36
+ - name: {{cap.appName}}-db
37
+ - name: {{cap.appName}}-auth
38
38
  provides:
39
- - name: sidecar
39
+ - name: mtx-sidecar
40
40
  properties:
41
41
  url: ${default-url}
42
42
  {{/cap.isJava}}
@@ -66,8 +66,8 @@ resources:
66
66
  onSubscription: ~{mtx-api/mtx-url}/mtx/v1/provisioning/tenant/{tenantId}
67
67
  {{/cap.isNodejs}}
68
68
  {{#cap.isJava}}
69
- getDependencies: ~${srv-api/srv-url}/mt/v1.0/subscriptions/dependencies
70
- onSubscription: ~${srv-api/srv-url}/mt/v1.0/subscriptions/tenants/{tenantId}
69
+ getDependencies: ~{srv-api/srv-url}/mt/v1.0/subscriptions/dependencies
70
+ onSubscription: ~{srv-api/srv-url}/mt/v1.0/subscriptions/tenants/{tenantId}
71
71
  {{/cap.isJava}}
72
72
  onSubscriptionAsync: false
73
73
  onUnSubscriptionAsync: false
@@ -1,9 +1,14 @@
1
+ const cds = require ('@sap/cds/lib'), { fs, path } = cds.utils
1
2
  const TemplateBase = require('../templateBase')
2
3
  const ProjectReader = require('../../util/projectReader')
3
- const { fse } = require('@sap/cds-foss')
4
- const path = require('path')
5
4
  const { OPTION_HANA, OPTION_XSUAA } = require('../../constants')
6
- const { srvNode, srvJava, saasRegistry, mtxSidecar, mtxAPI, srvAPI, hdiContainer, xsuaa } = require('../_merging/existences');
5
+
6
+ const {
7
+ srvNode, srvJava, // Server
8
+ mtxSidecar, // Additional Modules
9
+ saasRegistry, xsuaa, // BTP Services
10
+ providedMtxAPI, srvAPI, providedMtxSidecarAPI, requiredMtxSidecarAPI // APIs
11
+ } = require('../_merging/existences');
7
12
 
8
13
  module.exports = class MtxTemplate extends TemplateBase {
9
14
  constructor(projectPath, generator) {
@@ -19,36 +24,38 @@ module.exports = class MtxTemplate extends TemplateBase {
19
24
  const projectDescriptor = await this.projectReader.read()
20
25
 
21
26
  const mtaYAMLPath = path.join(this.projectPath, 'mta.yaml');
22
- if (!fse.existsSync(mtaYAMLPath)) {
23
- console.warn(`There is no MTA file in your project. Run \`cds add mta\` to add an MTA file or create the MTX services yourself.`)
24
- return;
25
- }
27
+
28
+ if (!fs.existsSync(mtaYAMLPath)) return
26
29
 
27
30
  const mergingRules = projectDescriptor.cap.isNodejs ?
28
31
  {
29
- existences: [srvNode, saasRegistry, mtxAPI, xsuaa],
32
+ existences: [srvNode, saasRegistry, providedMtxAPI, xsuaa],
30
33
  overwrites: [{
31
- in: xsuaa.ref,
34
+ in: xsuaa,
32
35
  keyPath: ["parameters", "config", "tenant-mode"],
33
36
  replacement: "shared"
34
37
  }],
35
- deletions: [hdiContainer],
36
38
  relationships: [{
37
- in: srvNode.ref,
39
+ in: srvNode,
38
40
  inKeyPath: ["requires"],
39
41
  into: "name",
40
- existences: [saasRegistry.ref],
42
+ existences: [saasRegistry],
41
43
  existenceKeyPath: ["name"],
42
44
  }],
43
45
  }
44
46
  :
45
47
  {
46
- existences: [srvJava, srvAPI, mtxSidecar, saasRegistry],
48
+ existences: [srvJava, srvAPI, mtxSidecar, xsuaa, saasRegistry, providedMtxSidecarAPI, requiredMtxSidecarAPI],
49
+ overwrites: [{
50
+ in: xsuaa,
51
+ keyPath: ["parameters", "config", "tenant-mode"],
52
+ replacement: "shared"
53
+ }],
47
54
  relationships: [{
48
- in: srvJava.ref,
55
+ in: srvJava,
49
56
  inKeyPath: ["requires"],
50
57
  into: "name",
51
- existences: [saasRegistry.ref, mtxSidecar.ref],
58
+ existences: [saasRegistry],
52
59
  existenceKeyPath: ["name"],
53
60
  }],
54
61
  }
@@ -59,13 +66,18 @@ module.exports = class MtxTemplate extends TemplateBase {
59
66
  projectDescriptor,
60
67
  mergingRules
61
68
  )
69
+
70
+ if (projectDescriptor.cap.hasApprouter) {
71
+ const ApprouterTemplate = require(`../approuter`)
72
+ const template = new ApprouterTemplate(this.projectPath, this.generator)
73
+ await template.runMTAMerging()
74
+ }
62
75
  }
63
76
 
64
77
  async runXSSecurityMerging() {
65
78
  const projectDescriptor = await this.projectReader.read()
66
- const mtxPath = projectDescriptor.cap.isJava ? 'mtx-sidecar' : ''
67
79
  await this.templateUtil.mergeJSON(
68
- path.join(this.projectPath, mtxPath, 'xs-security.json'),
80
+ path.join(this.projectPath, 'xs-security.json'),
69
81
  path.join(__dirname, 'files', 'xs-security.json.hbs'),
70
82
  projectDescriptor,
71
83
  {
@@ -131,11 +143,18 @@ module.exports = class MtxTemplate extends TemplateBase {
131
143
  }
132
144
 
133
145
  async run() {
134
- const projectDescriptor = await this.projectReader.read()
135
- const mtxPath = projectDescriptor.cap.isJava ? 'mtx-sidecar' : ''
136
- const packageJsonPath = path.join(this.projectPath, mtxPath, 'package.json')
137
- await this.templateUtil.mergeJSON(packageJsonPath, path.join(__dirname, 'files', 'cds.package.json'))
138
- await this.templateUtil.mergeJSON(packageJsonPath, path.join(__dirname, 'files', 'dependencies.package.json'))
146
+ const projectDescriptor = await this.projectReader.read(this.options)
147
+ if (projectDescriptor.cap.isNodejs) {
148
+ const packageJSONPath = path.join(this.projectPath, 'package.json')
149
+ const cdsTemplateFile = projectDescriptor.cap.for ? 'cds.package.json.hbs' : 'cds.package.json'
150
+ await this.templateUtil.mergeJSON(packageJSONPath, path.join(__dirname, 'files', cdsTemplateFile), projectDescriptor)
151
+ await this.templateUtil.mergeJSON(packageJSONPath, path.join(__dirname, 'files', 'dependencies.package.json'))
152
+ await this.templateUtil.sortDependencies(packageJSONPath)
153
+ } else {
154
+ const cdsrcJSONPath = path.join(this.projectPath, '.cdsrc.json')
155
+ await this.templateUtil.mergeJSON(cdsrcJSONPath, path.join(__dirname, 'files', 'java', '.cdsrc.json'))
156
+ await fs.copy(path.join(__dirname, 'files', 'java'), path.join(this.projectPath, 'mtx-sidecar'))
157
+ }
139
158
  await this.runXSSecurityMerging()
140
159
  await this.runMTAMerging()
141
160
  }
@@ -11,8 +11,11 @@ module.exports = class TemplateBase {
11
11
  * @constructor
12
12
  */
13
13
  constructor(projectPath, generator, dirName) {
14
- this.projectPath = path.resolve(projectPath);
14
+ if (generator.options && generator.options.for && typeof generator.options.for !== 'string') {
15
+ throw new Error('The --for argument must not be empty.')
16
+ }
15
17
  this.options = generator.options || {};
18
+ this.projectPath = path.resolve(projectPath);
16
19
  this.fsUtil = generator.fsUtil;
17
20
  this.logger = generator.logger;
18
21
  this.generator = generator;
@@ -0,0 +1,7 @@
1
+ {
2
+ "requires": {
3
+ "auth": {
4
+ "kind": "xsuaa"
5
+ }
6
+ }
7
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "requires": {
3
+ "[{{cap.for}}]": {
4
+ "auth": {
5
+ "kind": "xsuaa"
6
+ }
7
+ }
8
+ }
9
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "cds": {
3
3
  "requires": {
4
- "uaa": {
4
+ "auth": {
5
5
  "kind": "xsuaa"
6
6
  }
7
7
  }
@@ -0,0 +1,11 @@
1
+ {
2
+ "cds": {
3
+ "requires": {
4
+ "[{{cap.for}}]": {
5
+ "auth": {
6
+ "kind": "xsuaa"
7
+ }
8
+ }
9
+ }
10
+ }
11
+ }
@@ -3,10 +3,10 @@ modules:
3
3
  - name: {{cap.appName}}-srv
4
4
  type: {{cap.pLanguage}}
5
5
  requires:
6
- - name: {{cap.appName}}-uaa
6
+ - name: {{cap.appName}}-auth
7
7
 
8
8
  resources:
9
- - name: {{cap.appName}}-uaa{{#cap.isMultitenant}}-mt{{/cap.isMultitenant}}
9
+ - name: {{cap.appName}}-auth
10
10
  type: org.cloudfoundry.managed-service
11
11
  parameters:
12
12
  service: xsuaa
@@ -1,8 +1,9 @@
1
+ const fs = require('fs')
2
+ const path = require('path')
1
3
  const TemplateBase = require('../templateBase')
2
4
  const ProjectReader = require('../../util/projectReader')
3
- const { fse } = require('@sap/cds-foss')
4
- const path = require('path')
5
- const { srvNode, srvJava, xsuaa } = require('../_merging/existences');
5
+ const { srvNode, srvJava, xsuaa } = require('../_merging/existences')
6
+ const { PROJECT_TYPE } = require('../../constants');
6
7
 
7
8
  module.exports = class XsuaaTemplate extends TemplateBase {
8
9
  constructor(projectPath, generator) {
@@ -12,12 +13,11 @@ module.exports = class XsuaaTemplate extends TemplateBase {
12
13
 
13
14
  async runMTAMerging() {
14
15
  const projectDescriptor = await this.projectReader.read(this.options)
15
- const {projectPath} = this
16
+ const { projectPath } = this
17
+
16
18
  const mtaYAMLPath = path.join(projectPath, 'mta.yaml')
17
- if (!fse.existsSync(mtaYAMLPath)) {
18
- console.warn(`There is no MTA file in your project. Run \`cds add mta\` to add an MTA file or create the XSUAA services yourself.`)
19
- return
20
- }
19
+ if (!fs.existsSync(mtaYAMLPath)) return
20
+
21
21
  const srv = projectDescriptor.cap.isNodejs ? srvNode : srvJava
22
22
  await this.templateUtil.mergeYAML(
23
23
  mtaYAMLPath,
@@ -26,10 +26,10 @@ module.exports = class XsuaaTemplate extends TemplateBase {
26
26
  {
27
27
  existences: [srv, xsuaa],
28
28
  relationships: [{
29
- in: srv.ref,
29
+ in: srv,
30
30
  inKeyPath: ["requires"],
31
31
  into: "name",
32
- existences: [xsuaa.ref],
32
+ existences: [xsuaa],
33
33
  existenceKeyPath: ["name"],
34
34
  }],
35
35
  }
@@ -46,30 +46,46 @@ module.exports = class XsuaaTemplate extends TemplateBase {
46
46
  }
47
47
 
48
48
  async run() {
49
- const {projectPath} = this
49
+ const { projectPath } = this
50
50
  const templatePath = path.join(__dirname, 'files')
51
- const packageJSONPath = path.join(projectPath, 'package.json')
52
- await this.templateUtil.mergeJSON(packageJSONPath, `${templatePath}/cds.package.json`)
53
- await this.templateUtil.mergeJSON(packageJSONPath, `${templatePath}/dependencies.package.json`)
54
- const xsSecurityPath = path.join(projectPath, 'xs-security.json')
51
+ const projectDescriptor = await this.projectReader.read(this.options)
52
+
53
+ const projectType = await this.getProjectType();
54
+ switch (projectType) {
55
+ case PROJECT_TYPE.java: {
56
+ const cdsrcJSONPath = path.join(projectPath, '.cdsrc.json')
57
+ const cdsTemplateFile = projectDescriptor.cap.for ? 'cds.cdsrc.json.hbs' : 'cds.cdsrc.json'
58
+ const cdsTemplatePath = path.join(templatePath, cdsTemplateFile)
59
+ await this.templateUtil.mergeJSON(cdsrcJSONPath, cdsTemplatePath, projectDescriptor)
60
+ break
61
+ }
62
+ case PROJECT_TYPE.nodejs: {
63
+ const packageJSONPath = path.join(projectPath, 'package.json')
64
+ const cdsTemplateFile = projectDescriptor.cap.for ? 'cds.package.json.hbs' : 'cds.package.json'
65
+ const cdsTemplatePath = path.join(templatePath, cdsTemplateFile)
66
+ await this.templateUtil.mergeJSON(packageJSONPath, cdsTemplatePath, projectDescriptor)
67
+ const dependenciesTemplatePath = path.join(templatePath, 'dependencies.package.json')
68
+ await this.templateUtil.mergeJSON(packageJSONPath, dependenciesTemplatePath)
69
+ break
70
+ }
71
+ }
55
72
  const cds = require('../../../../lib/compile')
56
73
  const xsuaa = await (async () => { try {
57
- const models = await cds.load(`${projectPath}/srv`)
74
+ const models = await cds.load(path.join(projectPath, cds.env.folders.srv))
58
75
  return cds.compile.to.xsuaa(models)
59
76
  } catch (error) { /* ignore */ }
60
77
  })() || { scopes: [], attributes: [], 'role-templates': [] }
61
- const projectDescriptor = await this.projectReader.read(this.options)
62
- await this.fsUtil.writeJSON(xsSecurityPath, xsuaa)
63
-
64
- // TODO: Get rid of this by auto-creating a merging definition from
65
- // the current xs-security.json. This should also solve role-templates
66
- // being thrown out
67
- if (projectDescriptor.cap.isMultitenant) {
68
- const MtxTemplate = require(`../mtx`)
69
- const mtxTemplate = new MtxTemplate(this.projectPath, this.generator)
70
- await mtxTemplate.runXSSecurityMerging()
71
- }
72
78
 
79
+ const mergingSemantics = { existences: xsuaa.scopes.map(scope => ({
80
+ ref: scope.name,
81
+ keyPath: ["scopes"],
82
+ constraints: [{
83
+ comparisonKeyPath: ["name"],
84
+ value: scope.name
85
+ }],
86
+ }))}
87
+ const xsSecurityPath = path.join(projectPath, 'xs-security.json')
88
+ await this.templateUtil.mergeJSON(xsSecurityPath, xsuaa, projectDescriptor, mergingSemantics)
73
89
  await this.runMTAMerging()
74
90
  }
75
91
  }
@@ -69,20 +69,26 @@ export interface Logger {
69
69
  */
70
70
  export interface FsUtil {
71
71
  /**
72
- * Copies a file or folder from given source to destination.
73
- * @param source the source path
74
- * @param destination the destination path
75
- * @param options optional copy options
76
- * @param skipFileLog do not log files if true
72
+ * Writes the given string into a file.
73
+ * @param filepath the absolute file path
74
+ * @param content the string to serialize to JSON
77
75
  */
78
- copy(source: string, destination: string, options?: any, skipFileLog?: boolean): Promise<void>;
76
+ writeFile(filePath: string, content: string, skipLogFile?: boolean): Promise<void>;
79
77
 
80
78
  /**
81
- * Checks if given path exists.
82
- * @param filePath the absolute path
83
- * @returns true if given path exists, otherwise false
79
+ * Writes the given object as JSON into a file.
80
+ * @param filepath the absolute file path
81
+ * @param object the object to serialize to JSON
84
82
  */
85
- pathExists(filePath: string): Promise<boolean>;
83
+ writeJSON(filepath: string, object: any, options?: any): Promise<void>;
84
+
85
+ /**
86
+ * Writes YAML object
87
+ * @param filepath the absolute file path
88
+ * @param yaml the yaml object
89
+ * @param skipFileLog do not log files if true
90
+ */
91
+ writeYAML(filepath: string, yaml: any, skipFileLog?: boolean): Promise<void>;
86
92
 
87
93
  /**
88
94
  * Reads a file from given path.
@@ -95,23 +101,41 @@ export interface FsUtil {
95
101
  /**
96
102
  * Reads a JSON object from a file.
97
103
  * @param filePath the absolute file path
104
+ * @param projectDescriptor a project descriptor
98
105
  * @returns the file content as object
99
106
  */
100
- readJSON(filePath: string): Promise<any>;
107
+ readJSON(filePath: string, projectDescriptor: any): Promise<any>;
101
108
 
102
109
  /**
103
- * Writes the given string into a file.
104
- * @param filepath the absolute file path
105
- * @param content the string to serialize to JSON
110
+ * Reads a JSON object from a file.
111
+ * @param filePath the absolute file path
112
+ * @returns the file content as object
106
113
  */
107
- writeFile(filePath: string, content: string, skipLogFile?: boolean): Promise<void>;
114
+ readJSONC(filePath: string): Promise<any>;
108
115
 
109
116
  /**
110
- * Writes the given object as JSON into a file.
111
- * @param filepath the absolute file path
112
- * @param object the object to serialize to JSON
117
+ * Reads a JSON object from a file.
118
+ * @param filePath the absolute file path
119
+ * @param projectDescriptor a project descriptor
120
+ * @returns the file content as yaml object
113
121
  */
114
- writeJSON(filepath: string, object: any, options?: any): Promise<void>;
122
+ readYAML(filePath: string, projectDescriptor: any): Promise<any>;
123
+
124
+ /**
125
+ * Copies a file or folder from given source to destination.
126
+ * @param source the source path
127
+ * @param destination the destination path
128
+ * @param options optional copy options
129
+ * @param skipFileLog do not log files if true
130
+ */
131
+ copy(source: string, destination: string, options?: any, skipFileLog?: boolean): Promise<void>;
132
+
133
+ /**
134
+ * Checks if given path exists.
135
+ * @param filePath the absolute path
136
+ * @returns true if given path exists, otherwise false
137
+ */
138
+ pathExists(filePath: string): Promise<boolean>;
115
139
 
116
140
  /*
117
141
  * Methods mapping to fs-extra