@sap/cds-dk 7.9.5 → 8.0.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 (283) hide show
  1. package/CHANGELOG.md +2116 -0
  2. package/bin/add.js +18 -52
  3. package/bin/bind.js +2 -2
  4. package/bin/build.js +29 -4
  5. package/bin/cds.js +23 -11
  6. package/bin/compile/index.js +7 -6
  7. package/bin/completion/index.js +70 -46
  8. package/bin/completion/scripts/cds-bash.sh +4 -1
  9. package/bin/completion/scripts/cds-fish.fish +13 -0
  10. package/bin/completion/scripts/cds-ps.ps1 +2 -1
  11. package/bin/completion/scripts/cds-zsh.sh +2 -1
  12. package/bin/deploy/index.js +6 -5
  13. package/bin/deploy/to-sqlite.js +2 -2
  14. package/bin/extend.js +19 -50
  15. package/bin/help.js +2 -2
  16. package/bin/init.js +10 -77
  17. package/bin/login.js +13 -5
  18. package/bin/migrate.js +1 -1
  19. package/bin/pull.js +11 -0
  20. package/bin/repl.js +3 -0
  21. package/bin/test.js +5 -0
  22. package/bin/version.js +7 -7
  23. package/bin/watch.js +1 -10
  24. package/lib/bind/KubernetesApiAccessor.js +10 -9
  25. package/lib/build/buildTaskEngine.js +11 -7
  26. package/lib/build/buildTaskFactory.js +15 -43
  27. package/lib/build/buildTaskProviderFactory.js +16 -44
  28. package/lib/build/constants.js +3 -3
  29. package/lib/build/index.js +2 -2
  30. package/lib/build/{buildPlugin.js → plugin.js} +65 -46
  31. package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/Chart.yaml +1 -1
  32. package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/values.yaml +1 -1
  33. package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/service-instance/Chart.yaml +1 -1
  34. package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/service-instance/templates/_helpers.tpl +7 -0
  35. package/lib/build/plugins/helm/files/subcharts/service-instance/templates/servicebinding.yaml +32 -0
  36. package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/service-instance/templates/serviceinstance.yaml +3 -0
  37. package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/service-instance/values.schema.json +63 -0
  38. package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/service-instance/values.yaml +23 -1
  39. package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/Chart.yaml +1 -1
  40. package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/deployment.yaml +2 -0
  41. package/lib/build/plugins/helm/files/subcharts/web-application/templates/hpa.yaml +22 -0
  42. package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/pod-disruption-budget.yaml +1 -0
  43. package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/values.schema.json +49 -0
  44. package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/values.yaml +8 -2
  45. package/lib/{init/template/helm/files/chart → build/plugins/helm/files}/templates/_deployment_helpers.tpl +5 -0
  46. package/lib/build/plugins/helm/files/templates/_helpers.tpl +13 -0
  47. package/lib/build/plugins/helm/index.js +81 -0
  48. package/lib/build/plugins.js +12 -15
  49. package/lib/build/provider/featureToggleBuildPlugin.js +7 -39
  50. package/lib/build/provider/hana/2migration.js +168 -124
  51. package/lib/build/provider/hana/index.js +20 -25
  52. package/lib/build/provider/hana/template/package.json +4 -3
  53. package/lib/build/provider/internalBuildPlugin.js +32 -97
  54. package/lib/build/provider/internalBuildTaskProvider.js +10 -46
  55. package/lib/build/provider/java/index.js +2 -3
  56. package/lib/build/provider/mtx/index.js +5 -4
  57. package/lib/build/provider/mtx-extension/index.js +5 -2
  58. package/lib/build/provider/mtx-sidecar/index.js +2 -2
  59. package/lib/build/util.js +83 -12
  60. package/lib/compile/to-mermaid.js +108 -0
  61. package/lib/compile/to_asyncapi.js +7 -0
  62. package/lib/compile/to_openapi.js +7 -0
  63. package/lib/deploy/to-hana/hana.js +37 -34
  64. package/lib/deploy/to-hana/hdiDeployUtil.js +8 -6
  65. package/lib/env/schemas/cds-rc.js +1 -1
  66. package/lib/import/common.js +2 -2
  67. package/lib/import/odata/metadataconverter/MetadataConverter.js +4 -4
  68. package/lib/import/odata/v2parser.js +83 -197
  69. package/lib/import/odata/v4parser.js +1 -38
  70. package/lib/import/openapi/importOpenAPI.js +164 -42
  71. package/lib/index.js +10 -12
  72. package/lib/init/bas.js +91 -0
  73. package/lib/init/constants.js +16 -10
  74. package/lib/init/index.js +72 -150
  75. package/lib/init/merge.js +12 -20
  76. package/lib/init/mvn.js +103 -150
  77. package/lib/init/plugin.js +11 -7
  78. package/lib/init/projectReader.js +53 -19
  79. package/lib/init/registries/mta.js +51 -6
  80. package/lib/init/template/application-logging/files/package.json.hbs +7 -0
  81. package/lib/init/template/application-logging/index.js +13 -1
  82. package/lib/init/template/approuter/files/containerize.yaml.hbs +10 -0
  83. package/lib/init/template/approuter/files/mta.yaml.hbs +1 -2
  84. package/lib/init/template/approuter/files/values.yaml.hbs +19 -4
  85. package/lib/init/template/approuter/files/xs-app.json.hbs +12 -3
  86. package/lib/init/template/approuter/index.js +29 -25
  87. package/lib/init/template/attachments/files/mta.yaml.hbs +14 -0
  88. package/lib/init/template/attachments/files/package.json.hbs +5 -0
  89. package/lib/init/template/attachments/files/values.yaml +7 -0
  90. package/lib/init/template/attachments/index.js +53 -0
  91. package/lib/init/template/audit-logging/files/mta.yaml.hbs +14 -0
  92. package/lib/init/template/audit-logging/files/package.json.hbs +7 -0
  93. package/lib/init/template/audit-logging/index.js +66 -0
  94. package/lib/init/template/cf-manifest/index.js +4 -0
  95. package/lib/init/template/completion/completionSetup.js +54 -33
  96. package/lib/init/template/completion/index.js +7 -1
  97. package/lib/init/template/connectivity/index.js +4 -4
  98. package/lib/init/template/containerize/files/containerize.yaml.hbs +26 -0
  99. package/lib/init/template/containerize/index.js +24 -0
  100. package/lib/init/template/data/index.js +4 -0
  101. package/lib/init/template/destination/files/mta.yaml.hbs +25 -1
  102. package/lib/init/template/destination/index.js +12 -2
  103. package/lib/init/template/enterprise-messaging/index.js +6 -3
  104. package/lib/init/template/enterprise-messaging-shared/index.js +5 -1
  105. package/lib/init/template/extensibility/files/package.json.hbs +1 -1
  106. package/lib/init/template/extensibility/files/xs-security.json.hbs +2 -8
  107. package/lib/init/template/extensibility/index.js +3 -1
  108. package/lib/init/template/file-based-messaging/index.js +4 -0
  109. package/lib/init/template/h2/index.js +4 -0
  110. package/lib/init/template/hana/files/containerize.yaml.hbs +10 -0
  111. package/lib/init/template/hana/files/db/package.json +3 -2
  112. package/lib/init/template/hana/files/package.json.hbs +4 -7
  113. package/lib/init/template/hana/files/values.yaml.hbs +1 -2
  114. package/lib/init/template/hana/index.js +15 -7
  115. package/lib/init/template/helm/files/Chart.yaml.hbs +2 -3
  116. package/lib/init/template/helm/files/values.schema.json +2173 -0
  117. package/lib/init/template/helm/files/values.yaml.hbs +11 -6
  118. package/lib/init/template/helm/index.js +77 -18
  119. package/lib/init/template/helm-unified-runtime/index.js +19 -56
  120. package/lib/init/template/html5-repo/files/app-package.json.hbs +11 -7
  121. package/lib/init/template/html5-repo/files/manifest.json +13 -0
  122. package/lib/init/template/html5-repo/files/mta.yaml.hbs +41 -8
  123. package/lib/init/template/html5-repo/files/ui5-deploy.yaml.hbs +21 -0
  124. package/lib/init/template/html5-repo/files/ui5.yaml.hbs +2 -29
  125. package/lib/init/template/html5-repo/files/values.yaml.hbs +6 -2
  126. package/lib/init/template/html5-repo/files/xs-app.json.hbs +21 -8
  127. package/lib/init/template/html5-repo/index.js +33 -30
  128. package/lib/init/template/http/index.js +36 -12
  129. package/lib/init/template/java/index.js +18 -12
  130. package/lib/init/template/kafka/index.js +4 -0
  131. package/lib/init/template/lint/index.js +7 -2
  132. package/lib/init/template/liquibase/index.js +4 -0
  133. package/lib/init/template/local-messaging/index.js +4 -0
  134. package/lib/init/template/malware-scanner/files/mta.yaml.hbs +14 -0
  135. package/lib/init/template/malware-scanner/files/package.json.hbs +17 -0
  136. package/lib/init/template/malware-scanner/files/values.yaml +7 -0
  137. package/lib/init/template/malware-scanner/index.js +47 -0
  138. package/lib/init/template/mta/files/mta.yaml.hbs +3 -3
  139. package/lib/init/template/mta/files/package.json +1 -1
  140. package/lib/init/template/mta/index.js +4 -0
  141. package/lib/init/template/mtx/index.js +4 -0
  142. package/lib/init/template/multitenancy/files/containerize.yaml.hbs +10 -0
  143. package/lib/init/template/multitenancy/files/mta.yaml.hbs +0 -1
  144. package/lib/init/template/multitenancy/files/package.json.hbs +1 -1
  145. package/lib/init/template/multitenancy/files/package.sidecar.json.hbs +6 -5
  146. package/lib/init/template/multitenancy/files/values.yaml.hbs +14 -24
  147. package/lib/init/template/multitenancy/index.js +50 -28
  148. package/lib/init/template/nodejs/files/eslint.config.mjs +2 -0
  149. package/lib/init/template/nodejs/files/package.json.hbs +2 -3
  150. package/lib/init/template/nodejs/index.js +4 -0
  151. package/lib/init/template/notifications/files/mta.yaml.hbs +2 -2
  152. package/lib/init/template/notifications/index.js +4 -0
  153. package/lib/init/template/pipeline/files/.pipeline/config.yml +1 -1
  154. package/lib/init/template/pipeline/files/Jenkinsfile +1 -1
  155. package/lib/init/template/pipeline/index.js +4 -0
  156. package/lib/init/template/portal/files/mta.yaml.hbs +52 -0
  157. package/lib/init/template/portal/files/package.json.hbs +11 -0
  158. package/lib/init/template/portal/files/package.sidecar.json +7 -0
  159. package/lib/init/template/portal/files/portal-site/CommonDataModel.json.hbs +97 -0
  160. package/lib/init/template/portal/files/portal-site/i18n/catalog.properties +1 -0
  161. package/lib/init/template/portal/files/portal-site/i18n/catalog_de.properties +1 -0
  162. package/lib/init/template/portal/files/portal-site/i18n/group.properties +1 -0
  163. package/lib/init/template/portal/files/portal-site/i18n/group_de.properties +1 -0
  164. package/lib/init/template/portal/index.js +84 -0
  165. package/lib/init/template/postgres/index.js +5 -1
  166. package/lib/init/template/redis-messaging/index.js +4 -0
  167. package/lib/init/template/sample/files/app/admin-books/webapp/i18n/i18n_de.properties +3 -0
  168. package/lib/init/template/sample/files/app/admin-books/webapp/i18n/i18n_en.properties +3 -0
  169. package/lib/init/template/sample/files/app/admin-books/webapp/manifest.json +13 -1
  170. package/lib/init/template/sample/files/app/browse/webapp/i18n/i18n.properties +2 -2
  171. package/lib/init/template/sample/files/app/browse/webapp/i18n/i18n_de.properties +3 -0
  172. package/lib/init/template/sample/files/app/browse/webapp/i18n/i18n_en.properties +4 -0
  173. package/lib/init/template/sample/files/app/browse/webapp/manifest.json +3 -3
  174. package/lib/init/template/sample/files/app/index.html +1 -1
  175. package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Authors.csv +5 -5
  176. package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Books.csv +6 -6
  177. package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Books_texts.csv +5 -5
  178. package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Genres.csv +16 -16
  179. package/lib/init/template/sample/files/nodejs/cat-service.js +2 -2
  180. package/lib/init/template/sample/files/package.json.hbs +3 -0
  181. package/lib/init/template/sample/index.js +16 -9
  182. package/lib/init/template/sqlite/index.js +4 -0
  183. package/lib/init/template/tiny-sample/files/nodejs/db/data/my.bookshop-Books.csv +3 -3
  184. package/lib/init/template/tiny-sample/files/nodejs/srv/cat-service.cds.hbs +1 -1
  185. package/lib/init/template/tiny-sample/index.js +4 -0
  186. package/lib/init/template/toggles/files/package.json.hbs +1 -1
  187. package/lib/init/template/toggles/index.js +4 -0
  188. package/lib/init/template/typer/index.js +4 -0
  189. package/lib/init/template/typescript/files/package.json +12 -0
  190. package/lib/init/template/typescript/files/tsconfig.json +13 -0
  191. package/lib/init/template/typescript/index.js +39 -0
  192. package/lib/init/template/workzone/index.js +5 -0
  193. package/lib/init/template/workzone-standard/files/manifest.json.hbs +6 -0
  194. package/lib/init/template/workzone-standard/index.js +30 -0
  195. package/lib/init/template/xsuaa/files/package.json.hbs +1 -1
  196. package/lib/init/template/xsuaa/files/values.yaml.hbs +3 -2
  197. package/lib/init/template/xsuaa/index.js +11 -7
  198. package/lib/init/validate.js +27 -0
  199. package/lib/lint/generators.js +1 -1
  200. package/lib/lint/io.js +25 -7
  201. package/lib/mtx/auth_manager.js +64 -30
  202. package/lib/mtx/download_legacy.js +2 -2
  203. package/lib/mtx/index.js +0 -4
  204. package/lib/mtx/params.js +32 -38
  205. package/lib/mtx/pull.js +151 -43
  206. package/lib/mtx/push.js +3 -3
  207. package/lib/mtx/settings_manager.js +75 -35
  208. package/lib/mtx/tenant_action.js +1 -1
  209. package/lib/mtx/util/cf.js +1 -1
  210. package/lib/mtx/util/fs.js +26 -1
  211. package/lib/mtx/util/logging.js +7 -3
  212. package/lib/util/command.js +0 -2
  213. package/lib/util/fs.js +2 -3
  214. package/lib/util/question.js +28 -0
  215. package/lib/util/term.js +5 -3
  216. package/npm-shrinkwrap.json +226 -1087
  217. package/package.json +13 -8
  218. package/bin/activate.js +0 -77
  219. package/lib/compile/asyncapi/channels.js +0 -22
  220. package/lib/compile/asyncapi/components/messageTraits/index.js +0 -89
  221. package/lib/compile/asyncapi/components/messages/index.js +0 -173
  222. package/lib/compile/asyncapi/components/schemas/annotations.js +0 -33
  223. package/lib/compile/asyncapi/components/schemas/array.js +0 -8
  224. package/lib/compile/asyncapi/components/schemas/cache.js +0 -14
  225. package/lib/compile/asyncapi/components/schemas/definition.js +0 -187
  226. package/lib/compile/asyncapi/components/schemas/enum.js +0 -16
  227. package/lib/compile/asyncapi/components/schemas/examples.js +0 -10
  228. package/lib/compile/asyncapi/components/schemas/index.js +0 -14
  229. package/lib/compile/asyncapi/components/schemas/localized.js +0 -29
  230. package/lib/compile/asyncapi/components/schemas/primitiveElement.js +0 -41
  231. package/lib/compile/asyncapi/components/schemas/ref.js +0 -45
  232. package/lib/compile/asyncapi/components/schemas/utils.js +0 -108
  233. package/lib/compile/asyncapi/index.js +0 -247
  234. package/lib/compile/asyncapi/message.js +0 -13
  235. package/lib/compile/asyncapi/utils.js +0 -27
  236. package/lib/compile/openapi/csdl2openapi.js +0 -2448
  237. package/lib/compile/openapi/index.js +0 -68
  238. package/lib/init/template/helm/files/chart/templates/NOTES.txt +0 -14
  239. package/lib/init/template/helm/files/chart/templates/_helpers.tpl +0 -28
  240. package/lib/init/template/helm/files/chart/values.root.schema.json +0 -61
  241. package/lib/init/template/helm/files/chart/values.schema.json +0 -366
  242. package/lib/init/template/helm-unified-runtime/files/Chart.yaml.hbs +0 -10
  243. package/lib/init/template/helm-unified-runtime/files/templates/_deployment_helpers.tpl +0 -90
  244. package/lib/init/template/helm-unified-runtime/files/templates/_helpers.tpl +0 -28
  245. package/lib/init/template/helm-unified-runtime/files/values.root.schema.json +0 -61
  246. package/lib/init/template/helm-unified-runtime/files/values.schema.json +0 -366
  247. package/lib/init/template/helm-unified-runtime/files/values.yaml.hbs +0 -26
  248. package/lib/init/template/helm-unified-runtime/package.json +0 -4
  249. package/lib/init/template/multitenancy/files/mtxs-configmap-java-approuter.yaml +0 -20
  250. package/lib/init/template/multitenancy/files/mtxs-configmap-java.yaml +0 -18
  251. package/lib/init/template/multitenancy/files/mtxs-configmap-nodejs-approuter.yaml +0 -12
  252. package/lib/init/template/multitenancy/files/mtxs-configmap-nodejs.yaml +0 -12
  253. package/lib/init/template/multitenancy/files/saas-registry-secret.yaml +0 -9
  254. package/lib/init/template/nodejs/files/eslint.config.js +0 -13
  255. package/lib/init/template/notebook/index.js +0 -11
  256. package/lib/init/template/samples/index.js +0 -9
  257. package/lib/mtx/activate.js +0 -238
  258. package/lib/mtx/extend.js +0 -173
  259. package/lib/util/exec.d.ts +0 -54
  260. package/lib/util/exec.js +0 -211
  261. /package/lib/{init/template/approuter/files → build/plugins/helm/files/plugins/approuter}/approuter-configmap.yaml +0 -0
  262. /package/lib/{init/template/connectivity/files → build/plugins/helm/files/plugins/connectivity}/connectivity-proxy-info.yaml +0 -0
  263. /package/lib/{init/template/html5-repo/files → build/plugins/helm/files/plugins/html5-repo}/html5-apps-deployer-configmap.yaml +0 -0
  264. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/templates/_helpers.tpl +0 -0
  265. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/templates/job.yaml +0 -0
  266. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/templates/secret.yaml +0 -0
  267. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/templates/service-account.yaml +0 -0
  268. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/templates/service-binding.yaml +0 -0
  269. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/values.schema.json +0 -0
  270. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/NOTES.txt +0 -0
  271. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/_api.tpl +0 -0
  272. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/_helpers.tpl +0 -0
  273. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/api-rule.yaml +0 -0
  274. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/network-policy.yaml +0 -0
  275. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/rbac.yaml +0 -0
  276. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/secret.yaml +0 -0
  277. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/service-account.yaml +0 -0
  278. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/service-binding.yaml +0 -0
  279. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/service.yaml +0 -0
  280. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/virtual-service.yaml +0 -0
  281. /package/lib/{init/template/helm-unified-runtime → build/plugins/helm}/files/templates/NOTES.txt +0 -0
  282. /package/lib/init/template/{nodejs/files → java}/.cdsrc.json +0 -0
  283. /package/lib/init/template/tiny-sample/files/nodejs/db/{data-model.cds → schema.cds} +0 -0
@@ -4,25 +4,14 @@ const cds = require('../../cds')
4
4
  const { hasJavaNature, getDefaultModelOptions, BuildError, hasOptionValue, normalizePath } = require('../util')
5
5
  const BuildTaskProvider = require('../buildTaskProvider')
6
6
  const { FILE_EXT_CDS, BUILD_TASK_HANA, BUILD_TASK_FIORI, BUILD_TASK_JAVA, BUILD_TASK_JAVA_CF, BUILD_TASK_NODEJS, BUILD_TASK_NODE_CF, BUILD_TASK_MTX,
7
- BUILD_TASK_PREFIX, BUILD_TASKS, BUILD_TASK_MTX_SIDECAR, MTX_SIDECAR_FOLDER, BUILD_TASK_MTX_EXTENSION, NODEJS_MODEL_EXCLUDE_LIST,
7
+ BUILD_TASKS, BUILD_TASK_MTX_SIDECAR, MTX_SIDECAR_FOLDER, BUILD_TASK_MTX_EXTENSION, NODEJS_MODEL_EXCLUDE_LIST,
8
8
  IGNORE_DEFAULT_MODELS, CONTENT_WS } = require("../constants")
9
9
  const ResourcesTarBuilder = require('./mtx/resourcesTarBuilder')
10
10
  const DEBUG = cds.debug('cli|build')
11
11
 
12
12
  class InternalBuildTaskProvider extends BuildTaskProvider {
13
- constructor() {
14
- super()
15
- // ensure that classic mtx is not used in combination with cds-dk@7
16
- if (InternalBuildTaskProvider._isClassicMtx()) {
17
- throw new BuildError(`@sap/cds-mtx is deprecated and not supported by @sap/cds-dk >= 7.
18
- Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/docs/guides/multitenancy/old-mtx-migration or install @sap/cds-dk version 6 instead.`)
19
- }
20
- }
21
-
22
13
  providesTask(key) {
23
- return BUILD_TASKS.includes(key.for) || key.use && key.use.startsWith(BUILD_TASK_PREFIX)
24
- // REVISIT: do not support different build task implementations of the same build task ID defined by 'for'
25
- // return (BUILD_TASKS.includes(key.for) && !key.use) || (key.use && key.use.startsWith(BUILD_TASK_PREFIX))
14
+ return BUILD_TASKS.includes(key.for)
26
15
  }
27
16
 
28
17
  async lookupTasks(tasks, dependencies) {
@@ -30,10 +19,6 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
30
19
  }
31
20
 
32
21
  async applyTaskDefaults(task) {
33
- const taskFor = InternalBuildTaskProvider._getForValueFromTask(task)
34
- task.for = task.for || taskFor
35
- task.use = task.use || `${BUILD_TASK_PREFIX}/${taskFor}`
36
-
37
22
  // src folder needs to be initialized first
38
23
  InternalBuildTaskProvider._setDefaultSrcFolder(task)
39
24
 
@@ -41,7 +26,7 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
41
26
  }
42
27
 
43
28
  getPlugin(task) {
44
- return require(`./${InternalBuildTaskProvider._getForValueFromTask(task)}`)
29
+ return require(`./${task.for}`)
45
30
  }
46
31
 
47
32
  async _createTasks(tasks, dependencies) {
@@ -202,7 +187,7 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
202
187
  }
203
188
 
204
189
  // mtxs nodejs app without sidecar
205
- if (!InternalBuildTaskProvider._hasJavaNature(src)) {
190
+ if (!hasJavaNature()) {
206
191
  DEBUG?.("MTX Nodejs app without sidecar")
207
192
  return {
208
193
  for: BUILD_TASK_MTX,
@@ -218,7 +203,7 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
218
203
  return null
219
204
  }
220
205
  let task = null
221
- if (InternalBuildTaskProvider._hasJavaNature(src)) {
206
+ if (hasJavaNature()) {
222
207
  task = this._createJavaTask(src, taskOptions)
223
208
  } else {
224
209
  task = this._createNodeTask(src, taskOptions)
@@ -243,6 +228,9 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
243
228
 
244
229
  _createNodeTask(src, taskOptions) {
245
230
  DEBUG?.("found implementation technology Nodejs")
231
+ if (!fs.existsSync(path.join(cds.root, 'package.json'))) {
232
+ throw new BuildError(`No 'package.json' found in project root folder '${cds.root}'`)
233
+ }
246
234
  return {
247
235
  src: src,
248
236
  for: BUILD_TASK_NODEJS,
@@ -254,17 +242,6 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
254
242
  return !!cds.env.extends
255
243
  }
256
244
 
257
- static _isClassicMtx() {
258
- function _hasMtxDependency() {
259
- try {
260
- return !!require(path.join(cds.root, 'package.json'))?.dependencies?.['@sap/cds-mtx']
261
- } catch (e) {
262
- return false
263
- }
264
- }
265
- return /true/i.test(process.env.OLD_MTX) || _hasMtxDependency()
266
- }
267
-
268
245
  /**
269
246
  * Distinguishes whether the Nodejs project is a Streamlined MTX (cds >=6) or an old MTX project.
270
247
  */
@@ -303,14 +280,14 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
303
280
  task.src ||= normalizePath(cds.env.folders.srv)
304
281
  break
305
282
  default:
306
- throw new Error(`Unknown build task '${task.use || task.for}'`)
283
+ throw new Error(`Unknown build task '${task.for}'`)
307
284
  }
308
285
  }
309
286
 
310
287
  static async _setDefaultModel(task) {
311
288
  const ws = hasOptionValue(task.options?.[CONTENT_WS], true) || cds.cli.options?.ws
312
289
  // REVISIT: filter nodejs bootstrap service models for Java - issues/12770#issuecomment-1805719
313
- const filter = this._hasJavaNature() ? (m) => !NODEJS_MODEL_EXCLUDE_LIST.includes(m) : null
290
+ const filter = hasJavaNature() ? (m) => !NODEJS_MODEL_EXCLUDE_LIST.includes(m) : null
314
291
  let taskModelPaths = task.options?.model
315
292
  if (taskModelPaths && !Array.isArray(taskModelPaths)) {
316
293
  taskModelPaths = [taskModelPaths]
@@ -336,19 +313,6 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
336
313
  }
337
314
  }
338
315
 
339
- /**
340
- * Returns whether this project is a java project or not.
341
- * @param {string} srv - the folder name of the service module
342
- */
343
- static _hasJavaNature(srv = cds.env.folders.srv) {
344
- srv = this._getModuleFolder(Array.isArray(srv) ? srv : [srv])
345
- return hasJavaNature([cds.root, srv && path.join(cds.root, srv)])
346
- }
347
-
348
- static _getForValueFromTask(task) {
349
- return task.for ? task.for : task.use && task.use.substring(BUILD_TASK_PREFIX.length + 1)
350
- }
351
-
352
316
  /**
353
317
  * Determines the module folder from the given list that may represent files or folders w or w/o .cds file extension.
354
318
  * @param {Array} filesOrFolders
@@ -24,9 +24,8 @@ class JavaBuildPlugin extends EdmxBuildPlugin {
24
24
  await this._compileForJava(model, compileDest)
25
25
 
26
26
  if (!this.hasBuildOption(CONTENT_EDMX, false)) {
27
- // generate edmx files containing all features
28
- // REVISIT: localized edmx for backward compatibility
29
- if (!this.hasBuildOption(CONTENT_LOCALIZED_EDMX, false)) {
27
+ // generate edmx files containing all features - localized edmx for backward compatibility
28
+ if (this.hasBuildOption(CONTENT_LOCALIZED_EDMX, true)) {
30
29
  await this.compileToEdmx(model, compileDest, { [FLAVOR_LOCALIZED_EDMX]: true })
31
30
  }
32
31
  // non-localized edmx
@@ -1,4 +1,4 @@
1
- /* eslint-disable no-empty */
1
+
2
2
  const fs = require('fs')
3
3
  const path = require('path')
4
4
  const cds = require('../../../cds')
@@ -9,16 +9,17 @@ const { BuildError } = require('../../util')
9
9
 
10
10
  class MtxBuildPlugin extends EdmxBuildPlugin {
11
11
  get priority() {
12
- // should be scheduled after 'hana' build tasks are finished
13
- return EdmxBuildPlugin.PRIORITY_MIN_VALUE
12
+ // must run after 'hana' build task
13
+ return super.priority - 10
14
14
  }
15
+
15
16
  init() {
16
17
  super.init()
17
18
 
18
19
  // this build task only supports nodejs mtxs apps without sidecar
19
20
  if (cds.env['project-nature'] === 'java') {
20
21
  throw new BuildError(`@sap/cds-mtx is deprecated and not supported by @sap/cds-dk >= 7. This also applies to the 'mtx' build task in Java projects.
21
- Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/docs/guides/multitenancy/old-mtx-migration or install @sap/cds-dk version 6 instead.`)
22
+ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/docs/guides/multitenancy/old-mtx-migration.`)
22
23
  }
23
24
  }
24
25
 
@@ -133,8 +133,11 @@ class MtxExtensionBuildPlugin extends InternalBuildPlugin {
133
133
  }
134
134
 
135
135
  static _getSaasPkgPath() {
136
+ if (!cds.env.extends) {
137
+ throw new BuildError(`Missing configuration 'cds.extends' in package.json`)
138
+ }
136
139
  // cds.env.extends holds the SaaS app package name, also if the extends field is defined on root level
137
- let saasPkgPath = this._getWorkspacePath(cds.env.extends || '_base')
140
+ let saasPkgPath = this._getWorkspacePath(cds.env.extends)
138
141
  if (!saasPkgPath) {
139
142
  // older projects might not have a workspace definition
140
143
  saasPkgPath = this._getNodeModulesPath(saasPkgPath)
@@ -156,7 +159,7 @@ class MtxExtensionBuildPlugin extends InternalBuildPlugin {
156
159
  }
157
160
 
158
161
  static _getNodeModulesPath() {
159
- const saasPkgPath = path.join(cds.root, 'node_modules', cds.env.extends || '_base')
162
+ const saasPkgPath = path.join(cds.root, 'node_modules', cds.env.extends)
160
163
  if (!fs.existsSync(saasPkgPath)) {
161
164
  throw new BuildError(`The SaaS application base model is missing. Did you execute 'cds pull' and 'npm install'?`)
162
165
  }
@@ -12,8 +12,8 @@ const DEFAULT_MAIN_FOLDER = "_main"
12
12
 
13
13
  class MtxSidecarBuildPlugin extends NodejsBuildPlugin {
14
14
  get priority() {
15
- // should be scheduled after 'hana' build tasks are finished
16
- return NodejsBuildPlugin.PRIORITY_MIN_VALUE
15
+ // must run after 'hana' build task
16
+ return super.priority - 10
17
17
  }
18
18
  init() {
19
19
  super.init()
package/lib/build/util.js CHANGED
@@ -28,18 +28,9 @@ function setProperty(src, segments, value) {
28
28
 
29
29
  /**
30
30
  * Returns whether this project is a java project or not.
31
- * @param {Array} dirs - the absolute path names to check.
32
31
  */
33
- function hasJavaNature(dirs) {
34
- return dirs.flat().reduce((acc, dir) => {
35
- if (dir) {
36
- const file = path.join(dir, 'pom.xml')
37
- if (fs.existsSync(file)) {
38
- acc.push(file)
39
- }
40
- }
41
- return acc
42
- }, []).length > 0
32
+ function hasJavaNature() {
33
+ return [cds.env.folders.srv, '.'].some(f => f && fs.existsSync(path.join(cds.root, f, 'pom.xml')))
43
34
  }
44
35
 
45
36
  /**
@@ -176,8 +167,18 @@ async function pathExists(path) {
176
167
  * @returns the paths are relative to 'cds.root'.
177
168
  */
178
169
  async function getWorkspaces(resolve = false, devDependencies = true, wsRoot = cds.root) {
170
+ let pgkJsonWsRoot
171
+ try {
172
+ pgkJsonWsRoot = require(path.join(wsRoot, 'package.json'))
173
+ } catch (e) {
174
+ if (e.code === 'MODULE_NOT_FOUND') {
175
+ DEBUG?.(`No package.json found in project '${wsRoot}', skipping workspace resolution.`)
176
+ return []
177
+ }
178
+ throw e
179
+ }
180
+
179
181
  const workspaces = []
180
- const pgkJsonWsRoot = require(path.join(wsRoot, 'package.json'))
181
182
  let pgkJson = pgkJsonWsRoot
182
183
  if (wsRoot !== cds.root) {
183
184
  pgkJson = require(path.join(cds.root, 'package.json'))
@@ -201,6 +202,44 @@ async function getWorkspaces(resolve = false, devDependencies = true, wsRoot = c
201
202
  return workspaces
202
203
  }
203
204
 
205
+ /**
206
+ * This JavaScript function filterFeaturePaths is used to filter and categorize file paths
207
+ * from a given model into two categories: base and features.
208
+ * @param {*} model - represents a data model. It's expected to have a $sources property which is an array of file paths.
209
+ * @param {*} modelPaths - an array of file paths.
210
+ * @returns
211
+ */
212
+ function filterFeaturePaths(model, modelPaths) {
213
+ const ftsName = path.dirname(cds.env.features.folders || 'fts/*')
214
+ const regex = new RegExp(`[/|\\\\]+${ftsName}[/|\\\\]+(?<ftName>[^/|\\\\]*)`)
215
+ const sources = { base: [] }
216
+
217
+ // add ROOT source file paths for the base model
218
+ sources.base = cds.resolve(modelPaths).reduce((acc, file) => {
219
+ const match = file.match(regex)
220
+ if (!match) {
221
+ acc.push(file)
222
+ }
223
+ return acc
224
+ }, [])
225
+
226
+ // add source file paths for the features
227
+ sources.features = model['$sources'].reduce((acc, file) => {
228
+ const match = file.match(regex)
229
+ if (match) {
230
+ const { ftName } = match.groups
231
+ //feature
232
+ if (!acc[ftName]) {
233
+ acc[ftName] = []
234
+ }
235
+ acc[ftName].push(file)
236
+ }
237
+ return acc
238
+ }, {})
239
+
240
+ return sources
241
+ }
242
+
204
243
  /**
205
244
  * Read installed npm workspaces using 'npm ls -ws --json'.
206
245
  * @returns {Array} list of package paths, or an empty array if either
@@ -280,6 +319,36 @@ function _filterModelPaths(modelPaths, filter) {
280
319
  return [...model].filter(m => filter ? filter(m) : true).map(m => normalizePath(m))
281
320
  }
282
321
 
322
+ /**
323
+ * Returns a set of files found in the given directory and its subdirectories.
324
+ * @param {string} srcDir - the directory to search for files
325
+ * @param {Function} filter - the filter function to apply to the found files
326
+ * @param {Array} files - the set of files to add the found files to
327
+ * @returns {Array} files found in the given directory and its subdirectories
328
+ */
329
+ function getFiles(srcDir, filter, files = []) {
330
+ function handleResource(entry, filter, files) {
331
+ if (!filter || filter.call(this, entry)) {
332
+ const stats = fs.lstatSync(entry)
333
+ if (stats.isDirectory()) {
334
+ getFiles(entry, filter, files)
335
+ } else if (stats.isFile() || stats.isSymbolicLink()) {
336
+ files.push(entry)
337
+ }
338
+ }
339
+ }
340
+ let entries = []
341
+ try {
342
+ entries = fs.readdirSync(srcDir)
343
+ } catch (e) {
344
+ // ignore if not existing
345
+ }
346
+ entries.map(subDirEntry => path.join(srcDir, subDirEntry)).forEach((entry) => {
347
+ handleResource(entry, filter, files)
348
+ })
349
+ return files
350
+ }
351
+
283
352
  /**
284
353
  * Return gnu-style error string for location `loc`:
285
354
  * - 'File:Line:Col' without `loc.end`
@@ -371,6 +440,8 @@ module.exports = {
371
440
  normalizePath,
372
441
  pathExists,
373
442
  getWorkspaces,
443
+ filterFeaturePaths,
444
+ getFiles,
374
445
  BuildMessage,
375
446
  BuildError
376
447
  }
@@ -0,0 +1,108 @@
1
+ const cds = require('../cds')
2
+
3
+ module.exports = function to_mermaid (model, options={}) {
4
+ options = Object.assign({
5
+ assocnames: false, // include association names
6
+ elements : false, // include all elements { falsy | 'all'|true | 'keys' }
7
+ min : false, // minify the model, i.e. remove unused definitions, available in CLI
8
+ namespaces: true, // group entities by namespace/service
9
+ queries : false, // include relations for queries
10
+ service : undefined // filter service by name, available in CLI
11
+ }, cds.env.mermaid ?? {}, options)
12
+
13
+ const elemOpts = options.elements === 'none' ? false : options.elements
14
+ if (options.min) model = cds.minify(model)
15
+
16
+ model = cds.linked(model)
17
+ const allServices = model.all('service')
18
+
19
+ // filter by one service if its name is given or only one service is present
20
+ const srvFilter = options.service ?? (Object.keys(allServices).length === 1 ? allServices[0].name : undefined)
21
+ if (srvFilter && !model.definitions[srvFilter]) {
22
+ throw new Error(`Service "${srvFilter}" not found among ${model.all('service').map(s => s.name).sort()}`)
23
+ }
24
+
25
+ const seenEntities = new Set()
26
+ const namespaces = {}
27
+ const entityFilter = e => !e.name.startsWith('cds.') && !e.name.endsWith('.texts')
28
+
29
+ let diag = ''
30
+
31
+ // if requested, filter by one service
32
+ model.all('service')
33
+ .filter (srv => !srvFilter || srv.name === srvFilter)
34
+ .forEach(srv => {
35
+ namespaces[srv.name] = []
36
+ model.entities(srv)
37
+ .filter (entityFilter)
38
+ .forEach (e => {
39
+ namespaces[srv.name].push(e)
40
+ seenEntities.add(e.name)
41
+ })
42
+ })
43
+
44
+ // group other namespaces/services
45
+ if (options.namespaces) {
46
+ model.all('entity')
47
+ .filter (e => !seenEntities.has(e.name))
48
+ .filter (entityFilter)
49
+ .forEach (e => {
50
+ const ns = e.name.slice(0,e.name.lastIndexOf('.'))
51
+ if (!srvFilter || ns === srvFilter) {
52
+ namespaces[ns] = namespaces[ns] || []
53
+ namespaces[ns].push(e)
54
+ seenEntities.add(e.name)
55
+ }
56
+ })
57
+
58
+ // create namespace groups and classes
59
+ Object.keys(namespaces).forEach(ns => {
60
+ if (!diag.length) diag = `classDiagram\n`
61
+ diag += ` namespace ${ns.replaceAll('.','_')} {\n`
62
+ namespaces[ns].forEach (e => {
63
+ const simpleName = e.name.slice(e.name.lastIndexOf('.')+1)
64
+ diag += ` class \`${e.name}\``
65
+ diag += `["${simpleName}"]` // simple name as label
66
+ if (elemOpts) {
67
+ diag += ` {\n`
68
+ e.elements.forEach (el => {
69
+ if ((elemOpts === 'all' || elemOpts === true) || (el.key && elemOpts == 'keys')) {
70
+ diag += ` +${el._type?.replace('cds.','')} ${el.name}`
71
+ diag += `\n`
72
+ }
73
+ })
74
+ diag += ` }`
75
+ }
76
+ diag += `\n`
77
+ })
78
+ diag += ` }\n`
79
+ })
80
+ diag += `\n`
81
+ }
82
+
83
+ // add associations, either from collected entities or all entities
84
+ const entities = seenEntities.size
85
+ ? Array.from(seenEntities).map(name => model.definitions[name])
86
+ : model.all('entity').filter (entityFilter) // if no grouping and no service filter is on
87
+ entities.forEach(e => {
88
+ if (!diag.length) diag = `classDiagram\n`
89
+ e.elements.forEach (el => {
90
+ if (el instanceof cds.Association) {
91
+ if (el.target.endsWith('.texts')) return
92
+ const type = el.type === 'cds.Composition' ? '*-->' : '-->'
93
+ const card = el.cardinality?.max === '*' ? '"*"' : ''
94
+ diag += ` \`${e.name}\` ${type} ${card} \`${el.target}\``
95
+ if (options.assocnames) {
96
+ diag += `: ${el.name}`
97
+ }
98
+ diag += `\n`
99
+ }
100
+ })
101
+ // add relations for queries
102
+ if (e.query && options.queries) {
103
+ diag += ` \`${e.name}\` ..> \`${e.query.target.name}\`\n`
104
+ }
105
+ })
106
+
107
+ return diag.trim()
108
+ }
@@ -0,0 +1,7 @@
1
+ const { compile } = require('@cap-js/asyncapi')
2
+
3
+ function cds_compile_to_asyncapi (csn, options) {
4
+ return compile(csn, options)
5
+ }
6
+
7
+ module.exports = cds_compile_to_asyncapi
@@ -0,0 +1,7 @@
1
+ const { compile } = require('@cap-js/openapi')
2
+
3
+ function cds_compile_to_openapi (csn, options) {
4
+ return compile(csn, options)
5
+ }
6
+
7
+ module.exports = cds_compile_to_openapi
@@ -36,7 +36,7 @@ module.exports = new class HanaDeployer {
36
36
  }
37
37
 
38
38
  async deploy(options = {}) {
39
- let { model, serviceName, tunnelAddress, vcapFile, undeployWhitelist, hdiOptions = {}, dry, storeCredentials } = options;
39
+ let { model, serviceName: pServiceName, tunnelAddress, vcapFile, undeployWhitelist, hdiOptions = {}, dry, storeCredentials } = options;
40
40
 
41
41
  options.for = options.for || 'hybrid';
42
42
 
@@ -51,7 +51,7 @@ Therefore, specifying the CDS model is not required when calling 'cds deploy'.`;
51
51
  }
52
52
 
53
53
  if (vcapFile) {
54
- console.log(`Using VCAP_SERVICES from file ${vcapFile} (beta feature).`);
54
+ console.log(`Using VCAP_SERVICES from file ${vcapFile}.`);
55
55
  }
56
56
 
57
57
  const fromFile = vcapFile && exists(vcapFile) ? await read(vcapFile) : {};
@@ -59,23 +59,22 @@ Therefore, specifying the CDS model is not required when calling 'cds deploy'.`;
59
59
  const vcapEnv = { ...fromEnv, ...fromFile };
60
60
 
61
61
  const warnings = [];
62
- if (serviceName && vcapEnv.VCAP_SERVICES?.hana?.[0].name !== serviceName) {
62
+ if (pServiceName && vcapEnv.VCAP_SERVICES?.hana?.[0].name !== pServiceName) {
63
63
  if (vcapFile) {
64
- warnings.push(`The specified service name '${serviceName}' was used; the information coming from --vcap-service file was ignored.`);
64
+ warnings.push(`The specified service name '${pServiceName}' was used; the information coming from --vcap-service file was ignored.`);
65
65
  } else if (Object.keys(fromEnv).length > 0) {
66
- warnings.push(`The specified service name '${serviceName}' was used; the information coming from environment variable VCAP_SERVICES was ignored.`);
66
+ warnings.push(`The specified service name '${pServiceName}' was used; the information coming from environment variable VCAP_SERVICES was ignored.`);
67
67
  }
68
68
  }
69
69
 
70
- const projectPath = cds.root;
71
70
  const buildResults = await this._build();
72
71
 
73
72
  if (process.env.TARGET_CONTAINER) {
74
73
  vcapEnv.TARGET_CONTAINER = process.env.TARGET_CONTAINER;
75
74
  }
76
75
 
77
- if (dry) {
78
- for (const { task } of buildResults) {
76
+ for (const { task } of buildResults) {
77
+ if (dry) {
79
78
  const model = await cds.load(task.src);
80
79
  const data = cds.compile.to.hdbtable(model);
81
80
  for (const [src, { file }] of data) {
@@ -83,23 +82,27 @@ Therefore, specifying the CDS model is not required when calling 'cds deploy'.`;
83
82
  console.log(src);
84
83
  console.log();
85
84
  }
86
- }
87
- } else {
88
- for (const { task } of buildResults) {
85
+ } else {
89
86
  const dest = task.dest;
90
87
 
88
+ let serviceName = pServiceName;
89
+ let serviceKeyName;
90
+ if (!serviceName && cds.env.requires.db?.binding?.instance) {
91
+ serviceName = cds.env.requires.db.binding.instance;
92
+ serviceKeyName = cds.env.requires.db.binding.key;
93
+ }
94
+
91
95
  if (undeployWhitelist) {
92
96
  console.log('Writing undeploy.json');
93
97
  await fs.write(path.join(dest, 'undeploy.json'), JSON.stringify(undeployWhitelist, null, 2));
94
98
  }
95
99
 
96
100
  const hasVCAPEnv = Object.keys(vcapEnv).length > 0;
97
- let serviceKeyName
98
101
  if (!serviceName && hasVCAPEnv) {
99
102
  await fs.mkdir(dest, { recursive: true });
100
103
  } else {
101
104
  const { cfServiceInstanceName, cfServiceInstanceKeyName, serviceKey } =
102
- await this._getOrCreateCFService(projectPath, dest, serviceName, tunnelAddress);
105
+ await this._getOrCreateCFService(dest, serviceName, serviceKeyName, tunnelAddress);
103
106
 
104
107
  serviceName ??= cfServiceInstanceName;
105
108
  serviceKeyName ??= cfServiceInstanceKeyName
@@ -108,7 +111,7 @@ Therefore, specifying the CDS model is not required when calling 'cds deploy'.`;
108
111
  }
109
112
 
110
113
  if (storeCredentials) {
111
- await this._addInstanceToDefaultEnvJson([dest, projectPath], cfServiceInstanceName, serviceKey);
114
+ await this._addInstanceToDefaultEnvJson([dest, cds.root], cfServiceInstanceName, serviceKey);
112
115
  }
113
116
  }
114
117
 
@@ -129,7 +132,7 @@ Therefore, specifying the CDS model is not required when calling 'cds deploy'.`;
129
132
  }
130
133
 
131
134
  if (storeCredentials) {
132
- await gitUtil.ensureFileIsGitignored('default-env.json', projectPath);
135
+ await gitUtil.ensureFileIsGitignored('default-env.json', cds.root);
133
136
  }
134
137
 
135
138
  console.log(`If not already done, use ${info('cds add hana')} to configure the project for SAP HANA.\n`);
@@ -146,7 +149,7 @@ Therefore, specifying the CDS model is not required when calling 'cds deploy'.`;
146
149
  }
147
150
 
148
151
 
149
- async _getOrCreateCFService(projectPath, currentModelFolder, serviceName, tunnelAddress) {
152
+ async _getOrCreateCFService(currentModelFolder, serviceName, serviceKeyName, tunnelAddress) {
150
153
  const modelName = path.basename(currentModelFolder);
151
154
 
152
155
  // get from param
@@ -155,7 +158,7 @@ Therefore, specifying the CDS model is not required when calling 'cds deploy'.`;
155
158
  if (serviceName) {
156
159
  cfServiceInstanceName = serviceName;
157
160
  } else {
158
- const cfServiceDescriptor = await mtaUtil.getHanaDbModuleDescriptor(projectPath, modelName);
161
+ const cfServiceDescriptor = await mtaUtil.getHanaDbModuleDescriptor(cds.root, modelName);
159
162
  cfServiceInstanceName = cfServiceDescriptor.hdiServiceName;
160
163
  cfServiceInstanceMta = cfServiceDescriptor.hdiService
161
164
  }
@@ -167,16 +170,16 @@ Therefore, specifying the CDS model is not required when calling 'cds deploy'.`;
167
170
  const cfConfig = cfServiceInstanceMta?.parameters?.config;
168
171
  const serviceInstance = await this.createHanaService(cfServiceInstanceName, cfConfig);
169
172
 
170
- const cfServiceInstanceKeyName = `${cfServiceInstanceName}-key`;
171
- let serviceKey = await cfUtil.getOrCreateServiceKey(serviceInstance, cfServiceInstanceKeyName, { permissions: 'development' });
172
- this._validateServiceKey(serviceKey, cfServiceInstanceKeyName);
173
+ const cfServiceInstanceKeyName = serviceKeyName ?? `${cfServiceInstanceName}-key`;
174
+ let credentials = await cfUtil.getOrCreateServiceKey(serviceInstance, cfServiceInstanceKeyName, { permissions: 'development' });
175
+ this._validateCredentials(credentials, cfServiceInstanceKeyName);
173
176
 
174
177
  if (tunnelAddress) {
175
178
  console.log(`Using tunnel address ${bold(tunnelAddress)} (beta feature)`);
176
- serviceKey = this._injectTunnelAddress(serviceKey, tunnelAddress)
179
+ credentials = this._injectTunnelAddress(credentials, tunnelAddress)
177
180
  }
178
181
 
179
- return { cfServiceInstanceName, cfServiceInstanceKeyName, serviceKey, serviceInstance }
182
+ return { cfServiceInstanceName, cfServiceInstanceKeyName, serviceKey: credentials, serviceInstance }
180
183
  }
181
184
 
182
185
 
@@ -198,18 +201,18 @@ Therefore, specifying the CDS model is not required when calling 'cds deploy'.`;
198
201
  }
199
202
 
200
203
 
201
- _validateServiceKey(serviceKey, cfServiceInstanceKey) {
202
- if (!serviceKey) {
204
+ _validateCredentials(credentials, cfServiceInstanceKey) {
205
+ if (!credentials) {
203
206
  throw `Could not create service key ${bold(cfServiceInstanceKey)}.`;
204
207
  }
205
208
 
206
- if (serviceKey['sm_url']) {
209
+ if (credentials['sm_url']) {
207
210
  throw `Service key credentials are matching to a Service Manager instance of a multitenant environment. Make sure there is no conflict with ${cfServiceInstanceKey}.`;
208
211
  }
209
212
 
210
213
  const fields = ['schema', 'user', 'password', 'url'];
211
214
  for (const field of fields) {
212
- if (!serviceKey[field]) {
215
+ if (!credentials[field]) {
213
216
  throw `Service key is missing mandatory field '${field}'. Make sure you are ${bold('not')} using a managed service.`;
214
217
  }
215
218
  }
@@ -266,17 +269,17 @@ Therefore, specifying the CDS model is not required when calling 'cds deploy'.`;
266
269
  }
267
270
 
268
271
 
269
- _injectTunnelAddress(serviceKey, tunnelAddress) {
272
+ _injectTunnelAddress(credentials, tunnelAddress) {
270
273
  if (!/\w+:\d+/.test(tunnelAddress)) {
271
274
  throw `Invalid tunnel address '${tunnelAddress}' - must be in form 'host:port'`;
272
275
  }
273
276
  const [tunnelHost, tunnelPort] = tunnelAddress.split(':')
274
- const { host, port } = serviceKey
275
- serviceKey.host = tunnelHost
276
- serviceKey.port = tunnelPort
277
- serviceKey.url = serviceKey.url.replace(`${host}:${port}`, tunnelAddress)
278
- serviceKey.hostname_in_certificate = host // make cert. verification happy, see xs2/hdideploy.js#527
279
- serviceKey.url = serviceKey.url + (serviceKey.url.includes('?') ? '&' : '?') + 'hostNameInCertificate=' + host
280
- return serviceKey
277
+ const { host, port } = credentials
278
+ credentials.host = tunnelHost
279
+ credentials.port = tunnelPort
280
+ credentials.url = credentials.url.replace(`${host}:${port}`, tunnelAddress)
281
+ credentials.hostname_in_certificate = host // make cert. verification happy, see xs2/hdideploy.js#527
282
+ credentials.url = credentials.url + (credentials.url.includes('?') ? '&' : '?') + 'hostNameInCertificate=' + host
283
+ return credentials
281
284
  }
282
285
  }