@sap/cds-dk 6.8.3 → 7.0.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 (218) hide show
  1. package/bin/activate.js +15 -7
  2. package/bin/add.js +29 -15
  3. package/bin/bind.js +49 -116
  4. package/bin/build.js +114 -0
  5. package/bin/cds.js +67 -24
  6. package/bin/compile/index.js +2 -2
  7. package/bin/deploy/index.js +46 -39
  8. package/bin/deploy/to-hana.js +11 -8
  9. package/bin/deploy/to-postgres.js +8 -2
  10. package/bin/deploy/to-sqlite.js +0 -1
  11. package/bin/env.js +75 -41
  12. package/bin/eval.js +3 -3
  13. package/bin/extend.js +17 -10
  14. package/bin/help.js +22 -21
  15. package/bin/import.js +10 -7
  16. package/bin/init.js +38 -17
  17. package/bin/login.js +69 -55
  18. package/bin/logout.js +12 -9
  19. package/bin/migrate.js +10 -4
  20. package/bin/pull.js +12 -5
  21. package/bin/push.js +24 -13
  22. package/bin/repl.js +1 -0
  23. package/bin/run.js +25 -0
  24. package/bin/subscribe.js +13 -8
  25. package/bin/unsubscribe.js +15 -8
  26. package/bin/upgrade.js +15 -9
  27. package/bin/util/log.js +24 -0
  28. package/bin/version.js +124 -0
  29. package/bin/watch.js +1 -35
  30. package/bin/watched.js +39 -0
  31. package/lib/bind/KubernetesApiAccessor.js +2 -2
  32. package/lib/bind/bindingManager.js +1 -1
  33. package/lib/bind/bindingUtil.js +0 -9
  34. package/lib/bind/cfKeyProvider.js +10 -72
  35. package/lib/bind/index.js +114 -0
  36. package/lib/bind/kubernetesCredentialsProvider.js +2 -2
  37. package/lib/bind/userCdsrcJsonStorageProvider.js +7 -44
  38. package/lib/build/buildTaskEngine.js +355 -0
  39. package/lib/build/buildTaskFactory.js +284 -0
  40. package/lib/build/buildTaskHandler.js +240 -0
  41. package/lib/build/buildTaskProvider.js +22 -0
  42. package/lib/build/buildTaskProviderFactory.js +182 -0
  43. package/lib/build/constants.js +56 -0
  44. package/lib/build/index.js +21 -0
  45. package/lib/build/provider/buildTaskHandlerEdmx.js +83 -0
  46. package/lib/build/provider/buildTaskHandlerFeatureToggles.js +132 -0
  47. package/lib/build/provider/buildTaskHandlerInternal.js +228 -0
  48. package/lib/build/provider/buildTaskProviderInternal.js +370 -0
  49. package/lib/build/provider/fiori/index.js +167 -0
  50. package/lib/build/provider/hana/2migration.js +179 -0
  51. package/lib/build/provider/hana/index.js +522 -0
  52. package/lib/build/provider/hana/migrationtable.js +472 -0
  53. package/lib/build/provider/hana/template/.hdiconfig-all +163 -0
  54. package/lib/build/provider/hana/template/.hdiconfig-cloud +137 -0
  55. package/lib/build/provider/hana/template/.hdinamespace +4 -0
  56. package/lib/build/provider/hana/template/package.json +12 -0
  57. package/lib/build/provider/hana/template/undeploy.json +5 -0
  58. package/lib/build/provider/java/index.js +93 -0
  59. package/lib/build/provider/java-cf/index.js +1 -0
  60. package/lib/build/provider/mtx/index.js +37 -0
  61. package/lib/build/provider/mtx/resourcesTarBuilder.js +94 -0
  62. package/lib/build/provider/mtx-extension/index.js +131 -0
  63. package/lib/build/provider/mtx-sidecar/index.js +138 -0
  64. package/lib/build/provider/node-cf/index.js +1 -0
  65. package/lib/build/provider/nodejs/index.js +178 -0
  66. package/lib/build/util.js +263 -0
  67. package/lib/cds.js +9 -21
  68. package/lib/client/auth_manager.js +39 -16
  69. package/lib/client/helper/dependency_helper.js +7 -6
  70. package/lib/client/push.js +2 -1
  71. package/lib/client/settings_manager.js +10 -39
  72. package/lib/deploy/to-hana/hana.js +273 -0
  73. package/lib/deploy/to-hana/hdiDeployUtil.js +68 -0
  74. package/lib/deploy/to-hana/mtaUtil.js +171 -0
  75. package/lib/import/asyncapi/importAsyncAPI.js +3 -2
  76. package/lib/import/asyncapi/index.js +5 -2
  77. package/lib/import/asyncapi/parserContext.js +67 -26
  78. package/lib/import/asyncapi/utils.js +34 -3
  79. package/lib/import/common.js +40 -30
  80. package/lib/import/importapi.js +36 -35
  81. package/lib/index.js +12 -17
  82. package/lib/init/constants.js +36 -71
  83. package/lib/init/index.js +18 -52
  84. package/lib/init/template/_merging/registry-mta.js +21 -3
  85. package/lib/init/template/approuter/files/mta.yaml.hbs +29 -29
  86. package/lib/init/template/approuter/files/values.yaml.hbs +5 -5
  87. package/lib/init/template/approuter/files/xs-app.json.hbs +8 -2
  88. package/lib/init/template/approuter/index.js +7 -8
  89. package/lib/init/template/auditlog/files/mta.yaml.hbs +5 -5
  90. package/lib/init/template/auditlog/files/package.json.hbs +13 -13
  91. package/lib/init/template/auditlog/index.js +3 -3
  92. package/lib/init/template/cf-manifest/files/manifest.yml.hbs +22 -22
  93. package/lib/init/template/cf-manifest/files/services-manifest.yml.hbs +3 -3
  94. package/lib/init/template/connectivity/files/mta.yaml.hbs +14 -0
  95. package/lib/init/template/connectivity/files/package.json.hbs +17 -0
  96. package/lib/init/template/connectivity/index.js +21 -4
  97. package/lib/init/template/data/index.js +5 -1
  98. package/lib/init/template/destination/files/mta.yaml.hbs +14 -0
  99. package/lib/init/template/destination/files/package.json.hbs +17 -0
  100. package/lib/init/template/{destinations → destination}/index.js +19 -13
  101. package/lib/init/template/enterprise-messaging/files/event-mesh.json.hbs +3 -3
  102. package/lib/init/template/enterprise-messaging/files/mta.yaml.hbs +5 -5
  103. package/lib/init/template/enterprise-messaging/files/package.json.hbs +9 -9
  104. package/lib/init/template/enterprise-messaging/files/xs-security.json.hbs +19 -0
  105. package/lib/init/template/enterprise-messaging/index.js +27 -6
  106. package/lib/init/template/enterprise-messaging-shared/files/event-mesh.json.hbs +3 -3
  107. package/lib/init/template/enterprise-messaging-shared/files/mta.yaml.hbs +5 -5
  108. package/lib/init/template/enterprise-messaging-shared/files/package.json.hbs +9 -9
  109. package/lib/init/template/enterprise-messaging-shared/index.js +4 -5
  110. package/lib/init/template/extensibility/files/package.json.hbs +10 -10
  111. package/lib/init/template/extensibility/index.js +8 -9
  112. package/lib/init/template/file-based-messaging/files/package.json.hbs +9 -9
  113. package/lib/init/template/file-based-messaging/index.js +3 -4
  114. package/lib/init/template/hana/files/db/package.json +1 -1
  115. package/lib/init/template/hana/files/mta.yaml.hbs +21 -21
  116. package/lib/init/template/hana/files/package.json.hbs +16 -22
  117. package/lib/init/template/hana/files/values.yaml.hbs +1 -1
  118. package/lib/init/template/hana/index.js +5 -15
  119. package/lib/init/template/helm/files/Chart.yaml.hbs +4 -4
  120. package/lib/init/template/helm/files/values.yaml.hbs +6 -6
  121. package/lib/init/template/helm/index.js +5 -10
  122. package/lib/init/template/helm/subcharts/content-deployment/Chart.yaml +2 -0
  123. package/lib/init/template/helm/subcharts/content-deployment/templates/_helpers.tpl +37 -31
  124. package/lib/init/template/helm/subcharts/content-deployment/templates/job.yaml +13 -14
  125. package/lib/init/template/helm/subcharts/content-deployment/templates/secret.yaml +2 -2
  126. package/lib/init/template/helm/subcharts/content-deployment/templates/service-account.yaml +1 -1
  127. package/lib/init/template/helm/subcharts/content-deployment/templates/service-binding.yaml +3 -3
  128. package/lib/init/template/helm/subcharts/content-deployment/values.md +116 -116
  129. package/lib/init/template/helm/subcharts/service-instance/Chart.yaml +2 -0
  130. package/lib/init/template/helm/subcharts/service-instance/templates/_helpers.tpl +9 -9
  131. package/lib/init/template/helm/subcharts/service-instance/templates/serviceinstance.yaml +2 -2
  132. package/lib/init/template/helm/subcharts/service-instance/values.md +15 -15
  133. package/lib/init/template/helm/subcharts/web-application/Chart.yaml +2 -0
  134. package/lib/init/template/helm/subcharts/web-application/templates/NOTES.txt +15 -0
  135. package/lib/init/template/helm/subcharts/web-application/templates/_helpers.tpl +23 -23
  136. package/lib/init/template/helm/subcharts/web-application/templates/api-rule.yaml +4 -4
  137. package/lib/init/template/helm/subcharts/web-application/templates/deployment.yaml +17 -17
  138. package/lib/init/template/helm/subcharts/web-application/templates/network-policy.yaml +24 -3
  139. package/lib/init/template/helm/subcharts/web-application/templates/pod-disruption-budget.yaml +3 -3
  140. package/lib/init/template/helm/subcharts/web-application/templates/secret.yaml +2 -2
  141. package/lib/init/template/helm/subcharts/web-application/templates/service-account.yaml +1 -1
  142. package/lib/init/template/helm/subcharts/web-application/templates/service-binding.yaml +3 -3
  143. package/lib/init/template/helm/subcharts/web-application/templates/service.yaml +3 -3
  144. package/lib/init/template/helm/subcharts/web-application/values.md +141 -123
  145. package/lib/init/template/helm/subcharts/web-application/values.schema.json +7 -0
  146. package/lib/init/template/helm/subcharts/web-application/values.yaml +1 -0
  147. package/lib/init/template/html5-repo/index.js +4 -5
  148. package/lib/init/template/java/index.js +5 -5
  149. package/lib/init/template/kibana-logging/files/mta.yaml.hbs +5 -5
  150. package/lib/init/template/kibana-logging/files/package.json.hbs +9 -9
  151. package/lib/init/template/kibana-logging/index.js +3 -4
  152. package/lib/init/template/lint/index.js +3 -3
  153. package/lib/init/template/mta/files/mta.yaml.hbs +14 -14
  154. package/lib/init/template/mta/files/package.json +5 -0
  155. package/lib/init/template/mta/index.js +12 -13
  156. package/lib/init/template/mtx/index.js +2 -2
  157. package/lib/init/template/multitenancy/files/mta.yaml.hbs +29 -27
  158. package/lib/init/template/multitenancy/files/package.json.hbs +17 -14
  159. package/lib/init/template/multitenancy/files/package.sidecar.json.hbs +7 -7
  160. package/lib/init/template/multitenancy/files/values.yaml.hbs +19 -19
  161. package/lib/init/template/multitenancy/index.js +14 -16
  162. package/lib/init/template/nodejs/files/package.json.hbs +1 -1
  163. package/lib/init/template/nodejs/index.js +5 -8
  164. package/lib/init/template/redis-messaging/files/mta.yaml.hbs +5 -5
  165. package/lib/init/template/redis-messaging/files/package.json.hbs +9 -9
  166. package/lib/init/template/redis-messaging/index.js +4 -5
  167. package/lib/init/template/sample/files/app/_i18n/i18n.properties +43 -0
  168. package/lib/init/template/sample/files/app/_i18n/i18n_de.properties +14 -0
  169. package/lib/init/template/sample/files/app/admin-books/fiori-service.cds +114 -0
  170. package/lib/init/template/sample/files/app/admin-books/webapp/Component.js +8 -0
  171. package/lib/init/template/sample/files/app/admin-books/webapp/i18n/i18n.properties +11 -0
  172. package/lib/init/template/sample/files/app/admin-books/webapp/manifest.json +129 -0
  173. package/lib/init/template/sample/files/app/appconfig/fioriSandboxConfig.json +57 -0
  174. package/lib/init/template/sample/files/app/common.cds +263 -0
  175. package/lib/init/template/sample/files/app/index.html +30 -0
  176. package/lib/init/template/sample/files/app/services.cds +5 -0
  177. package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Authors.csv +5 -0
  178. package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Books.csv +6 -0
  179. package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Books_texts.csv +5 -0
  180. package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Genres.csv +16 -0
  181. package/lib/init/template/sample/files/db/schema.cds +31 -0
  182. package/lib/init/template/sample/files/nodejs/admin-service.js +12 -0
  183. package/lib/init/template/sample/files/nodejs/cat-service.js +26 -0
  184. package/lib/init/template/sample/files/srv/admin-service.cds +5 -0
  185. package/lib/init/template/sample/files/srv/cat-service.cds +16 -0
  186. package/lib/init/template/sample/index.js +24 -0
  187. package/lib/init/template/sample-tiny/index.js +39 -0
  188. package/lib/init/template/samples/index.js +5 -56
  189. package/lib/init/template/sqlite/files/package.json.hbs +13 -13
  190. package/lib/init/template/sqlite/index.js +2 -2
  191. package/lib/init/template/templateBase.js +24 -1
  192. package/lib/init/template/toggles/files/package.json.hbs +10 -10
  193. package/lib/init/template/toggles/index.js +3 -3
  194. package/lib/init/template/typer/files/gitignore +1 -0
  195. package/lib/init/template/typer/files/package.json +8 -0
  196. package/lib/init/template/typer/files/xsconfig.json +9 -0
  197. package/lib/init/template/typer/index.js +36 -0
  198. package/lib/init/template/xsuaa/files/mta.yaml.hbs +12 -12
  199. package/lib/init/template/xsuaa/files/package.json.hbs +13 -13
  200. package/lib/init/template/xsuaa/files/values.yaml.hbs +8 -8
  201. package/lib/init/template/xsuaa/index.js +8 -19
  202. package/lib/init/util/merge.js +73 -59
  203. package/lib/init/util/mvn.js +21 -17
  204. package/lib/init/util/projectReader.js +49 -87
  205. package/lib/init/util/xml.js +14 -23
  206. package/lib/util/cfUtil.js +366 -0
  207. package/lib/util/command.js +3 -3
  208. package/lib/util/gitUtil.js +55 -0
  209. package/lib/util/version.js +27 -0
  210. package/npm-shrinkwrap.json +337 -275
  211. package/package.json +6 -6
  212. package/CHANGELOG.md +0 -1460
  213. package/bin/build/all.js +0 -88
  214. package/bin/build/index.js +0 -82
  215. package/lib/compile/index.js +0 -14
  216. /package/lib/init/template/{samples → sample-tiny}/files/nodejs/db/data/my.bookshop-Books.csv +0 -0
  217. /package/lib/init/template/{samples → sample-tiny}/files/nodejs/db/data-model.cds +0 -0
  218. /package/lib/init/template/{samples → sample-tiny}/files/nodejs/srv/cat-service.cds.hbs +0 -0
@@ -24,9 +24,21 @@ module.exports = class TemplateBase {
24
24
 
25
25
  /**
26
26
  * Returns an array of required templates. These templates will also be added if not already included.
27
- * @returns an array with depending templates, might be empty or null
27
+ * @function getDependencies
28
+ * @returns {Array} Dependent facets. Default is an empty array.
28
29
  */
29
30
  getDependencies() {
31
+ return []
32
+ }
33
+
34
+ /**
35
+ * Returns an array of related facets that might change the result of applying the current facet.
36
+ * Important: there must not be circular relationships between facets.
37
+ * @function getRelatedFacets()
38
+ * @returns {Array} Related facets. Default is an empty array.
39
+ */
40
+ getRelatedFacets() {
41
+ return []
30
42
  }
31
43
 
32
44
  /**
@@ -72,6 +84,17 @@ module.exports = class TemplateBase {
72
84
 
73
85
  }
74
86
 
87
+ /**
88
+ * Executes steps for related facets that are set up for the project.
89
+ */
90
+ async runRelatedMerging() {
91
+ for (const facet of this.getRelatedFacets()) {
92
+ const Template = require('./'+facet)
93
+ const template = new Template(this.generator)
94
+ if (Template.hasFacet(await this.getEnv(), this.options)) await template.runDependentMerging()
95
+ }
96
+ }
97
+
75
98
  /**
76
99
  * @abstract
77
100
  * Executes the given template.
@@ -1,20 +1,20 @@
1
1
  {
2
- {{#cap.isNodejs}}
2
+ {{#isNodejs}}
3
3
  "dependencies": {
4
- "@sap/cds-mtxs": "^1"
4
+ "@sap/cds-mtxs": "^1.9"
5
5
  },
6
6
  "cds": {
7
- {{/cap.isNodejs}}
7
+ {{/isNodejs}}
8
8
  "requires": {
9
- {{#cap.for}}
10
- "[{{cap.for}}]": {
11
- {{/cap.for}}
9
+ {{#profile}}
10
+ "[{{profile}}]": {
11
+ {{/profile}}
12
12
  "toggles": true
13
- {{#cap.for}}
13
+ {{#profile}}
14
14
  }
15
- {{/cap.for}}
15
+ {{/profile}}
16
16
  }
17
- {{#cap.isNodejs}}
17
+ {{#isNodejs}}
18
18
  }
19
- {{/cap.isNodejs}}
19
+ {{/isNodejs}}
20
20
  }
@@ -1,6 +1,6 @@
1
1
  const { join } = require('path')
2
2
  const { readProject } = require('../../util/projectReader')
3
- const { mergeJSON, sortDependencies } = require('../../util/merge')
3
+ const { mergeJSON, sort } = require('../../util/merge')
4
4
 
5
5
  module.exports = class TogglesTemplate extends require('../templateBase') {
6
6
 
@@ -10,9 +10,9 @@ module.exports = class TogglesTemplate extends require('../templateBase') {
10
10
 
11
11
  async run() {
12
12
  const projectDescriptor = await readProject(this.options)
13
- const { isNodejs , configFile} = projectDescriptor.cap
13
+ const { isNodejs , configFile} = projectDescriptor
14
14
  await mergeJSON(configFile, join(__dirname, 'files', 'package.json.hbs'), projectDescriptor)
15
- if (isNodejs) await sortDependencies('package.json')
15
+ if (isNodejs) await sort('package.json', 'dependencies')
16
16
  await this.runDependentMerging()
17
17
  }
18
18
  }
@@ -0,0 +1 @@
1
+ @cds-models
@@ -0,0 +1,8 @@
1
+ {
2
+ "devDependencies": {
3
+ "@cap-js/cds-typer": "^0"
4
+ },
5
+ "imports": {
6
+ "#cds-models/*": "./@cds-models/*/index.js"
7
+ }
8
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "compilerOptions": {
3
+ "checkJs": true,
4
+ "moduleResolution": "nodenext",
5
+ "paths": {
6
+ "#cds-models/*": ["./@cds-models/*"]
7
+ }
8
+ }
9
+ }
@@ -0,0 +1,36 @@
1
+ const { join } = require('path')
2
+ const { readProject } = require('../../util/projectReader')
3
+ const { mergeJSON, mergeGitignore } = require('../../util/merge')
4
+ const { TYPER } = require('../../constants').OPTIONS
5
+ const { exists, read } = require('../../../cds').utils
6
+
7
+ module.exports = class TyperTemplate extends require('../templateBase') {
8
+ async canRun() {
9
+ const projectDescriptor = await readProject(this.options)
10
+ if (projectDescriptor.isJava) {
11
+ console.warn(`WARNING: This appears to be a Java project. ${TYPER} facet is intended to be used in Node.js projects. Proceeding anyway`)
12
+ }
13
+ return true
14
+ }
15
+
16
+ async run() {
17
+ const template = name => join(__dirname, 'files', name)
18
+ const source = await read(template('xsconfig.json'))
19
+ let target = 'jsconfig.json'
20
+
21
+ if (exists('tsconfig.json')) {
22
+ source.compilerOptions.paths["#cds-models/*"][0] += '/index.ts'
23
+ target = 'tsconfig.json'
24
+ }
25
+ await mergeJSON('package.json', template('package.json'))
26
+ await mergeGitignore('.gitignore', template('gitignore'))
27
+ console.info('INFO: Adding this facet changed your .gitignore file to ignore generated types')
28
+ try {
29
+ await mergeJSON(target, source)
30
+ } catch (e) {
31
+ throw e instanceof SyntaxError
32
+ ? `SyntaxError in ${target}. This could indicate a JSON file with comments, which is not supported at this time. Remove all comments from ${target} and rerun or add the following entries manually:\n${JSON.stringify(source, null, 2)}`
33
+ : e
34
+ }
35
+ }
36
+ }
@@ -1,26 +1,26 @@
1
1
  ---
2
2
  modules:
3
- - name: {{cap.appName}}-srv
4
- type: {{cap.language}}
5
- path: {{& cap.srvPath}}
3
+ - name: {{appName}}-srv
4
+ type: {{language}}
5
+ path: {{& srvPath}}
6
6
  requires:
7
- - name: {{cap.appName}}-auth
7
+ - name: {{appName}}-auth
8
8
 
9
- {{#cap.isMultitenant}}
10
- - name: {{cap.appName}}-mtx
9
+ {{#isMultitenant}}
10
+ - name: {{appName}}-mtx
11
11
  type: nodejs
12
- path: {{#cap.isNodejs}}gen/{{/cap.isNodejs}}mtx/sidecar
12
+ path: {{#isNodejs}}gen/{{/isNodejs}}mtx/sidecar
13
13
  requires:
14
- - name: {{cap.appName}}-auth
15
- {{/cap.isMultitenant}}
14
+ - name: {{appName}}-auth
15
+ {{/isMultitenant}}
16
16
 
17
17
  resources:
18
- - name: {{cap.appName}}-auth
18
+ - name: {{appName}}-auth
19
19
  type: org.cloudfoundry.managed-service
20
20
  parameters:
21
21
  service: xsuaa
22
22
  service-plan: application
23
23
  path: ./xs-security.json
24
24
  config:
25
- xsappname: {{cap.appName}}-${org}-${space}
26
- tenant-mode: {{#cap.isMultitenant}}shared{{/cap.isMultitenant}}{{^cap.isMultitenant}}dedicated{{/cap.isMultitenant}}
25
+ xsappname: {{appName}}-${org}-${space}
26
+ tenant-mode: {{#isMultitenant}}shared{{/isMultitenant}}{{^isMultitenant}}dedicated{{/isMultitenant}}
@@ -1,28 +1,28 @@
1
1
  {
2
- {{#cap.isNodejs}}
2
+ {{#isNodejs}}
3
3
  "dependencies": {
4
4
  "@sap/xssec": "^3",
5
5
  "passport": "^0"
6
6
  },
7
7
  "cds": {
8
- {{/cap.isNodejs}}
8
+ {{/isNodejs}}
9
9
  "requires": {
10
- {{#cap.for}}
11
- "[{{cap.for}}]": {
12
- {{/cap.for}}
13
- {{#cap.shortcut}}
10
+ {{#profile}}
11
+ "[{{profile}}]": {
12
+ {{/profile}}
13
+ {{#shortcut}}
14
14
  "auth": "xsuaa"
15
- {{/cap.shortcut}}
16
- {{^cap.shortcut}}
15
+ {{/shortcut}}
16
+ {{^shortcut}}
17
17
  "auth": {
18
18
  "kind": "xsuaa"
19
19
  }
20
- {{/cap.shortcut}}
21
- {{#cap.for}}
20
+ {{/shortcut}}
21
+ {{#profile}}
22
22
  }
23
- {{/cap.for}}
23
+ {{/profile}}
24
24
  }
25
- {{#cap.isNodejs}}
25
+ {{#isNodejs}}
26
26
  }
27
- {{/cap.isNodejs}}
27
+ {{/isNodejs}}
28
28
  }
@@ -1,16 +1,16 @@
1
1
  ---
2
- {{#cap.isMultitenant}}
2
+ {{#isMultitenant}}
3
3
  sidecar:
4
4
  bindings:
5
5
  auth:
6
6
  serviceInstanceName: xsuaa
7
- {{/cap.isMultitenant}}
8
- {{#cap.hasApprouter}}
7
+ {{/isMultitenant}}
8
+ {{#hasApprouter}}
9
9
  approuter:
10
10
  bindings:
11
11
  auth:
12
12
  serviceInstanceName: xsuaa
13
- {{/cap.hasApprouter}}
13
+ {{/hasApprouter}}
14
14
  srv:
15
15
  bindings:
16
16
  auth:
@@ -19,10 +19,10 @@ xsuaa:
19
19
  serviceOfferingName: xsuaa
20
20
  servicePlanName: application
21
21
  parameters:
22
- xsappname: {{cap.appName}}
23
- tenant-mode: {{#cap.isMultitenant}}shared{{/cap.isMultitenant}}{{^cap.isMultitenant}}dedicated{{/cap.isMultitenant}}
24
- {{#cap.hasApprouter}}
22
+ xsappname: {{appName}}
23
+ tenant-mode: {{#isMultitenant}}shared{{/isMultitenant}}{{^isMultitenant}}dedicated{{/isMultitenant}}
24
+ {{#hasApprouter}}
25
25
  oauth2-configuration:
26
26
  redirect-uris:
27
27
  - https://*.<your-cluster-domain>/**
28
- {{/cap.hasApprouter}}
28
+ {{/hasApprouter}}
@@ -12,19 +12,23 @@ module.exports = class XsuaaTemplate extends require('../templateBase') {
12
12
  return env.requires?.auth?.kind === 'xsuaa'
13
13
  }
14
14
 
15
+ getRelatedFacets() {
16
+ return ['multitenancy', 'extensibility', 'enterprise-messaging']
17
+ }
18
+
15
19
  async run() {
16
20
  const projectDescriptor = await readProject(this.options)
17
- const { configFile } = projectDescriptor.cap
18
- projectDescriptor.cap.shortcut = !(await read(configFile)).cds?.requires?.auth?.kind
21
+ const { configFile } = projectDescriptor
22
+ projectDescriptor.shortcut = !(await read(configFile)).cds?.requires?.auth?.kind
19
23
  await mergeJSON(configFile, join(__dirname, 'files', 'package.json.hbs'), projectDescriptor, { forceOverwrite: true })
20
24
  await this.runDependentMerging()
21
25
  }
22
26
 
23
27
  async runDependentMerging( context = {}) {
24
28
  const projectDescriptor = await readProject(this.options)
25
- const { isMultitenant, isExtensible, hasMta, hasHelm, isJava, srvPath } = projectDescriptor.cap
29
+ const { isMultitenant, hasMta, hasHelm, isJava, srvPath } = projectDescriptor
26
30
 
27
- const cds = require('../../../../lib/compile')
31
+ const cds = require('../../../../lib')
28
32
  const xsSecurity = await (async () => { try {
29
33
  const models = await cds.load(cds.env.folders.srv)
30
34
  return cds.compile.to.xsuaa(models)
@@ -80,20 +84,5 @@ module.exports = class XsuaaTemplate extends require('../templateBase') {
80
84
  )
81
85
  if(isIndependentCommand) await writeMd5File(join('chart', '.cds-add-helm-files.md5'), context.newTrackingData);
82
86
  }
83
-
84
- // Re-applying the merging part of `cds add mtx` because cds.compile.to.xsuaa
85
- // has overwritten the existing `xs-security.json`.
86
- // TODO: Find a generic solution for situation like these.
87
- if (isMultitenant) {
88
- const MultitenancyTemplate = require(`../multitenancy`)
89
- const multitenancyTemplate = new MultitenancyTemplate(this.generator)
90
- await multitenancyTemplate.runDependentMerging(context)
91
- }
92
-
93
- if (isExtensible) {
94
- const ExtensibilityTemplate = require(`../extensibility`)
95
- const extensibilityTemplate = new ExtensibilityTemplate(this.generator)
96
- await extensibilityTemplate.runDependentMerging(context)
97
- }
98
87
  }
99
88
  }
@@ -1,6 +1,8 @@
1
1
  const YAML = require('@sap/cds-foss').yaml
2
2
  const { copy, read, write, exists } = require('../../cds').utils
3
3
  const { readYAML, writeYAML, readJSON } = require('../../util/fs')
4
+ const { EOL } = require('node:os')
5
+
4
6
 
5
7
  function _isObject(item) {
6
8
  return item && typeof item === 'object' && !Array.isArray(item)
@@ -25,18 +27,35 @@ function _deepMerge(target, source) {
25
27
  return target ?? source
26
28
  }
27
29
 
28
- async function sortDependencies(packageJSONPath) {
29
- const json = await read(packageJSONPath);
30
- json.dependencies = Object.fromEntries(
31
- Object.entries(json.dependencies).sort(([a],[b]) => a>b ? 1 : -1)
30
+ async function sort(path, key) {
31
+ const json = await read(path)
32
+ json[key] = Object.fromEntries(
33
+ Object.entries(json[key]).sort(([a],[b]) => a>b ? 1 : -1)
32
34
  )
33
- await write(packageJSONPath, json, { spaces: 2 });
35
+ await write(path, json, { spaces: 2 });
34
36
  }
35
37
 
38
+ /**
39
+ * @param {string} into - file path to merge into
40
+ * @param {string | string[]} from - either path to file (string) or lines from source gitignore (string[])
41
+ * @returns {string[]} the lines of the updated .gitignore
42
+ */
43
+ async function mergeGitignore (into, from) {
44
+ const source = typeof from === 'string' ? (await read(from)).split(EOL) : from
45
+
46
+ if (typeof into === 'string' && !exists(into)) {
47
+ return write(into, source.join(EOL))
48
+ }
49
+
50
+ const target = (await read(into)).split(EOL)
51
+ const enhanced = target.concat(source.filter(line => !target.includes(line)))
52
+ await write(into, enhanced.join(EOL))
53
+ return enhanced
54
+ }
55
+
36
56
  async function mergeJSON(into, from, projectDescriptor, semantics) {
37
57
  const source = typeof from === 'string' ? await readJSON(from, projectDescriptor) : from
38
58
 
39
-
40
59
  if (typeof into === 'string' && !exists(into)) {
41
60
  return write(into, source, { spaces: 2 })
42
61
  }
@@ -67,21 +86,21 @@ async function mergeYAML(into, from, projectDescriptor, semantics = {}) {
67
86
  return /* has no YAML */
68
87
  }
69
88
 
70
- const existenceMap = new Map, templateExistenceMap = new Map()
89
+ const entryMap = new Map, templateEntryMap = new Map()
71
90
 
72
91
  const { additions, overwrites, deletions, relationships } = semantics
73
- additions?.forEach(existence => {
74
- existenceMap.set(existence, undefined)
75
- templateExistenceMap.set(existence, undefined)
92
+ additions?.forEach(entry => {
93
+ entryMap.set(entry, undefined)
94
+ templateEntryMap.set(entry, undefined)
76
95
  })
77
96
  deletions?.forEach(deletion => {
78
- existenceMap.set(deletion.item, undefined)
97
+ entryMap.set(deletion.item, undefined)
79
98
  })
80
99
  relationships?.forEach(relationship => {
81
- const [existence] = relationship.into
82
- const [insertExistence] = relationship.insert
83
- const hash = insertExistence + ' -> ' + existence
84
- existenceMap.set(hash, undefined)
100
+ const [entry] = relationship.into
101
+ const [insertEntry] = relationship.insert
102
+ const hash = insertEntry + ' -> ' + entry
103
+ entryMap.set(hash, undefined)
85
104
  })
86
105
 
87
106
  let collectionStack = [target.contents]
@@ -90,8 +109,8 @@ async function mergeYAML(into, from, projectDescriptor, semantics = {}) {
90
109
  const _getYAMLProperty = (object, keyPath) => keyPath.split('.').reduce((p, k) => p && p.get(k), object)
91
110
 
92
111
  const _validateWhere = (node, dict, index) => {
93
- const _addToMap = existences => existences?.filter(existence => {
94
- let where = existence.in
112
+ const _addToMap = entries => entries?.filter(entry => {
113
+ let where = entry.in
95
114
  if (typeof where === 'string') return true // just a key path on the document root
96
115
  else where = where[0] // a more complex list of constraints, a sequence/array is involved
97
116
  const neededParent = dict.get(where)?.node
@@ -109,13 +128,13 @@ async function mergeYAML(into, from, projectDescriptor, semantics = {}) {
109
128
  })
110
129
  if (additions) _addToMap(additions)
111
130
  if (deletions) _addToMap(deletions.map(deletion => deletion.item))
112
- if (relationships) _addToMap(relationships?.map(({into: [existence]}) => existence).filter(e => e))
131
+ if (relationships) _addToMap(relationships?.map(({into: [entry]}) => entry).filter(e => e))
113
132
  }
114
133
 
115
134
  function _traverseYAMLNode(node, index, actions, templateNode) {
116
135
  let shifted = false
117
136
  if (YAML.isMap(node)) {
118
- actions?.visitMap && actions.visitMap(node, index)
137
+ actions.visitMap?.(node, index)
119
138
  const [collection] = collectionStack
120
139
  if (YAML.isSeq(collection)) {
121
140
  collectionStack.unshift(node)
@@ -135,7 +154,7 @@ async function mergeYAML(into, from, projectDescriptor, semantics = {}) {
135
154
  _traverseYAMLCollection(node, actions, templateNode)
136
155
  }
137
156
  } else if (node.value?.items || node.value && semantics.forceOverwrite) {
138
- _traverseYAMLNode(node.value, index, actions, templateNode && templateNode.value)
157
+ _traverseYAMLNode(node.value, index, actions, templateNode?.value)
139
158
  }
140
159
 
141
160
  if (node.value?.items || shifted) {
@@ -152,11 +171,11 @@ async function mergeYAML(into, from, projectDescriptor, semantics = {}) {
152
171
  // Map collection items to their semantic counterpart(s)
153
172
  collection.items.forEach((node, i) => {
154
173
  if (node.key) keyToIndex.set(node.key.value, i)
155
- const existence = [...existenceMap.entries()].find(([,value]) => value?.node === node)
156
- if (existence) {
157
- const [existenceKey] = existence
158
- const templateExistence = existenceKey && templateExistenceMap.get(existenceKey)
159
- const templateIndex = templateExistence?.index
174
+ const entry = [...entryMap.entries()].find(([,value]) => value?.node === node)
175
+ if (entry) {
176
+ const [entryKey] = entry
177
+ const templateEntry = entryKey && templateEntryMap.get(entryKey)
178
+ const templateIndex = templateEntry?.index
160
179
  if (templateIndex !== undefined) templateIndexToIndex.set(templateIndex, i)
161
180
  }
162
181
  if (!templateCollection) _traverseYAMLNode(node, i, actions)
@@ -172,7 +191,7 @@ async function mergeYAML(into, from, projectDescriptor, semantics = {}) {
172
191
  } else if (YAML.isPair(templateNode)) {
173
192
  const i = keyToIndex.get(templateNode.key.value)
174
193
  const [collection] = collectionStack
175
- const targetNode = collection.items && collection.items[i]
194
+ const targetNode = collection.items?.[i]
176
195
  if (targetNode) {
177
196
  _traverseYAMLNode(targetNode, templateIndex, actions, templateNode)
178
197
  } else if (actions.mergePair) {
@@ -189,36 +208,32 @@ async function mergeYAML(into, from, projectDescriptor, semantics = {}) {
189
208
  }
190
209
  _traverseYAMLCollection.bind(this)
191
210
 
192
- // 1. Validate the existences in the template
211
+ // 1. Register the entries in the template
193
212
  _traverseYAMLNode(source.contents, null, {
194
- visitMap: (node, index) => {
195
- _validateWhere(node, templateExistenceMap, index)
196
- }
213
+ visitMap: (node, index) => _validateWhere(node, templateEntryMap, index)
197
214
  })
198
215
 
199
- // 2. Validate the existences in the project
216
+ // 2. Register the entries in the project
200
217
  _traverseYAMLNode(target.contents, null, {
201
- visitMap: (node, index) => {
202
- _validateWhere(node, existenceMap, index)
203
- }
218
+ visitMap: (node, index) => _validateWhere(node, entryMap, index)
204
219
  })
205
220
 
206
- // 3. Apply overwrites to already found existences
221
+ // 3. Apply overwrites to already found entries
207
222
  overwrites?.forEach(({ item, withValue }) => {
208
223
  const keyPath = Array.isArray(item) && typeof item[0] === 'string' ? item[0] : typeof item === 'string' ? item : item[1]
209
- const inExistence = Array.isArray(item) && typeof item[0] === 'object' ? item[0] : typeof item === 'object' ? item : item[1]
210
- const node = inExistence && existenceMap.get(inExistence) ? existenceMap.get(inExistence).node : collectionStack[collectionStack.length - 1]
224
+ const inEntry = Array.isArray(item) && typeof item[0] === 'object' ? item[0] : typeof item === 'object' ? item : item[1]
225
+ const node = inEntry && entryMap.get(inEntry) ? entryMap.get(inEntry).node : collectionStack[collectionStack.length - 1]
211
226
  const keys = keyPath.split('.')
212
227
  if (!node.getIn(keys)) return
213
228
  _getYAMLProperty(node, keys.slice(0, keys.length - 1).join('.'))
214
229
  .set(keys[keys.length - 1], withValue)
215
230
  })
216
231
 
217
- // 4. Delete existences from the project (e.g. separate deployer module when adding mtx)
232
+ // 4. Delete entries from the project (e.g. separate deployer module when adding mtx)
218
233
  deletions?.forEach(({ item, relationships }) => {
219
- const existence = existenceMap.get(item)
220
- if (!existence) return
221
- existence.collection.delete(existence.index)
234
+ const entry = entryMap.get(item)
235
+ if (!entry) return
236
+ entry.collection.delete(entry.index)
222
237
 
223
238
  relationships?.forEach(relationship => {
224
239
  const [allWithinKeyPath, inKeyPath, into] = relationship.allWithin
@@ -226,14 +241,14 @@ async function mergeYAML(into, from, projectDescriptor, semantics = {}) {
226
241
  for (const child of parent.items) {
227
242
  const grandchild = _getYAMLProperty(child, inKeyPath)
228
243
  const i = grandchild?.items?.findIndex(node =>
229
- node.get(into) === _getProperty(existence.json, relationship.removeProperty)
244
+ node.get(into) === _getProperty(entry.json, relationship.removeProperty)
230
245
  ) ?? - 1
231
246
  if (i > -1) grandchild.delete(i)
232
247
  }
233
248
  })
234
249
  })
235
250
 
236
- // 5. Create missing existences and pairs
251
+ // 5. Create missing entries and pairs
237
252
  _traverseYAMLNode(target.contents, null, {
238
253
  mergePair: (collection, templateNode) => {
239
254
  if (YAML.isMap(collection)) {
@@ -245,8 +260,8 @@ async function mergeYAML(into, from, projectDescriptor, semantics = {}) {
245
260
  let [,parent] = collectionStack
246
261
  additions?.filter(addition => {
247
262
  if (typeof addition.in === 'string' || Array.isArray(addition.in) && typeof addition.in[0] === 'string') return true
248
- const inExistence = Array.isArray(addition.in) ? existenceMap.get(addition.in[0]) : existenceMap.get(addition.in)
249
- return inExistence?.node === parent
263
+ const inEntry = Array.isArray(addition.in) ? entryMap.get(addition.in[0]) : entryMap.get(addition.in)
264
+ return inEntry?.node === parent
250
265
  })
251
266
  .filter(addition => {
252
267
  const keyPath = typeof addition.in === 'string' ? addition.in : Array.isArray(addition.in) && typeof addition.in[0] === 'string' ? addition.in[0] : addition.in[1]
@@ -255,20 +270,18 @@ async function mergeYAML(into, from, projectDescriptor, semantics = {}) {
255
270
  if (keys.length > 1) parent = collectionStack[keys.length]
256
271
  return _getYAMLProperty(parent, keyPath) === targetNode
257
272
  })
258
- .filter(item => !existenceMap.get(item))
273
+ .filter(item => !entryMap.get(item))
259
274
  .forEach(item => {
260
- const templateNode = templateExistenceMap.get(item).node
275
+ const templateNode = templateEntryMap.get(item).node
261
276
  item.at !== undefined ? targetNode.items.splice(item.at, 0, templateNode) : targetNode.add(templateNode)
262
277
  })
263
278
  }
264
279
  },
265
280
  }, source.contents)
266
281
 
267
- // 6. Re-validate the existences in the project
282
+ // 6. Re-register the entries in the project
268
283
  _traverseYAMLNode(target.contents, null, {
269
- visitMap: (node, index) => {
270
- _validateWhere(node, existenceMap, index)
271
- }
284
+ visitMap: (node, index) => _validateWhere(node, entryMap, index)
272
285
  })
273
286
 
274
287
  // 7. Create missing relationships
@@ -278,22 +291,22 @@ async function mergeYAML(into, from, projectDescriptor, semantics = {}) {
278
291
  const targetJSON = YAML.parse(String(targetNode))
279
292
  const relationship = semantics.relationships?.filter(r => r)
280
293
  .find(relationship => {
281
- const [existence, keyPath] = relationship.into
282
- if (!existenceMap.get(existence)) return false
283
- const existingNode = _getYAMLProperty(existenceMap.get(existence).node, keyPath)
294
+ const [entry, keyPath] = relationship.into
295
+ if (!entryMap.get(entry)) return false
296
+ const existingNode = _getYAMLProperty(entryMap.get(entry).node, keyPath)
284
297
  return targetNode === existingNode
285
298
  })
286
299
  if (!relationship) return
287
300
 
288
301
  const intoKey = relationship.into[relationship.into.length - 1]
289
- const [existence, existenceKeyPath] = relationship.insert
290
- const missingPairs = [existence]
302
+ const [entry, entryKeyPath] = relationship.insert
303
+ const missingPairs = [entry]
291
304
  .filter(item =>
292
305
  !targetJSON.some(targetItem =>
293
- _getProperty(existenceMap.get(item).json, existenceKeyPath) === targetItem[intoKey]
306
+ _getProperty(entryMap.get(item).json, entryKeyPath) === targetItem[intoKey]
294
307
  )
295
308
  )
296
- .map(item => existenceMap.get(item).node.get(intoKey))
309
+ .map(item => entryMap.get(item).node.get(intoKey))
297
310
  missingPairs.forEach(pair => {
298
311
  targetNode.add({ [intoKey]: pair })
299
312
  })
@@ -347,7 +360,8 @@ async function removeFromYAMLArray(name, keyPath, aliasToRemove) {
347
360
  }
348
361
 
349
362
  module.exports = {
350
- sortDependencies,
363
+ sort,
364
+ mergeGitignore,
351
365
  mergeJSON,
352
366
  mergeYAML,
353
367
  removeFromYAML,