@sap/cds-dk 10.0.7 → 10.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (302) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/bin/add.js +7 -23
  3. package/bin/bind.js +10 -0
  4. package/bin/build.js +20 -34
  5. package/bin/cds.js +1 -1
  6. package/bin/compile/index.js +15 -41
  7. package/bin/completion/completionFs.js +11 -8
  8. package/bin/completion/index.js +592 -80
  9. package/bin/completion/scripts/cds.fish +568 -0
  10. package/bin/completion/scripts/cds.ps1 +329 -0
  11. package/bin/completion/scripts/cds.sh +261 -0
  12. package/bin/completion/scripts/cds.zsh +230 -0
  13. package/bin/completion/templates/cds-tmpl.fish +65 -0
  14. package/bin/completion/templates/cds-tmpl.ps1 +208 -0
  15. package/bin/completion/templates/cds-tmpl.sh +93 -0
  16. package/bin/completion/templates/cds-tmpl.zsh +74 -0
  17. package/bin/deploy/index.js +7 -1
  18. package/bin/deploy/options.js +25 -0
  19. package/{lib → bin}/deploy/to-hana/hana.js +8 -8
  20. package/{lib → bin}/deploy/to-hana/hdiDeployUtil.js +1 -1
  21. package/bin/deploy/{to-hana.js → to-hana/index.js} +1 -1
  22. package/{lib → bin}/deploy/to-hana/mtaUtil.js +1 -1
  23. package/bin/deploy/to-sql.js +0 -2
  24. package/bin/export.js +35 -5
  25. package/bin/help/export.md +3 -0
  26. package/bin/help.js +1 -5
  27. package/bin/import.js +6 -0
  28. package/bin/init.js +5 -24
  29. package/bin/inspect.js +6 -0
  30. package/bin/login.js +26 -20
  31. package/bin/pull.js +19 -6
  32. package/bin/push.js +19 -6
  33. package/bin/up.js +14 -11
  34. package/{lib → bin}/upgrade/constants.js +1 -1
  35. package/bin/{upgrade.js → upgrade/index.js} +2 -2
  36. package/{lib → bin}/upgrade/preflight/consistency.js +1 -1
  37. package/{lib → bin}/upgrade/preflight/index.js +1 -1
  38. package/{lib → bin}/upgrade/steps/analyze/index.js +1 -1
  39. package/{lib → bin}/upgrade/steps/install.js +1 -1
  40. package/{lib → bin}/upgrade/steps/openrewrite.js +1 -1
  41. package/{lib → bin}/upgrade/steps/removals.js +1 -1
  42. package/{lib → bin}/upgrade/steps/rewrite.js +1 -1
  43. package/{lib → bin}/upgrade/steps/verify.js +1 -1
  44. package/{lib/upgrade/index.js → bin/upgrade/upgrade.js} +2 -2
  45. package/{lib → bin}/upgrade/util/pom.js +2 -2
  46. package/{lib → bin}/upgrade/util/prompt.js +1 -1
  47. package/bin/util/containerize.js +8 -4
  48. package/bin/version.js +10 -1
  49. package/{lib → bin}/watch/hot-reload.js +1 -1
  50. package/bin/{watch.js → watch/index.js} +17 -9
  51. package/{lib → bin}/watch/livereload-connect.js +1 -1
  52. package/{lib → bin}/watch/vite-watch.js +1 -1
  53. package/{lib → bin}/watch/watched.js +2 -2
  54. package/lib/build/constants.js +1 -1
  55. package/lib/build/plugins/fiori/index.js +31 -2
  56. package/lib/build/plugins/internal.js +4 -2
  57. package/lib/build/plugins/mtx-sidecar/index.js +7 -8
  58. package/lib/build/plugins/nodejs/index.js +64 -7
  59. package/lib/compile/to_asyncapi.js +1 -1
  60. package/lib/env/schema.js +16 -0
  61. package/lib/env/schemas/cds-rc.js +1 -76
  62. package/lib/import/importapi.js +2 -3
  63. package/lib/import/message.js +0 -2
  64. package/lib/init/constants.js +2 -1
  65. package/lib/init/index.js +2 -2
  66. package/lib/init/merge.js +123 -280
  67. package/lib/init/plugin.js +3 -1
  68. package/lib/init/projectReader.js +22 -6
  69. package/lib/init/registries/xs-app.js +3 -5
  70. package/lib/init/template/ai/files/mta.yaml.hbs +1 -1
  71. package/lib/init/template/ai/index.js +14 -2
  72. package/lib/init/template/ams/index.js +2 -2
  73. package/lib/init/template/app-frontend/files/containerize.yaml.hbs +2 -2
  74. package/lib/init/template/app-frontend/index.js +4 -4
  75. package/lib/init/template/application-logging/index.js +2 -2
  76. package/lib/init/template/approuter/files/package.json +1 -1
  77. package/lib/init/template/approuter/index.js +8 -3
  78. package/lib/init/template/attachments/files/package.json.hbs +1 -1
  79. package/lib/init/template/attachments/index.js +2 -2
  80. package/lib/init/template/audit-logging/index.js +2 -2
  81. package/lib/init/template/cloud-logging/files/package.json.hbs +4 -4
  82. package/lib/init/template/cloud-logging/index.js +2 -2
  83. package/lib/init/template/completion/completionSetup.js +36 -39
  84. package/lib/init/template/connectivity/index.js +2 -2
  85. package/lib/init/template/data/as-csv.js +15 -5
  86. package/lib/init/template/data/as-json.js +114 -42
  87. package/lib/init/template/data/index.js +16 -2
  88. package/lib/init/template/destination/index.js +2 -2
  89. package/lib/init/template/dynatrace/files/package.json.hbs +3 -3
  90. package/lib/init/template/dynatrace/index.js +2 -2
  91. package/lib/init/template/enterprise-messaging/index.js +2 -2
  92. package/lib/init/template/enterprise-messaging-shared/index.js +2 -2
  93. package/lib/init/template/extensibility/files/mta.yaml.hbs +11 -0
  94. package/lib/init/template/extensibility/files/xs-security.json.hbs +1 -1
  95. package/lib/init/template/extensibility/index.js +3 -3
  96. package/lib/init/template/github-actions/index.js +2 -2
  97. package/lib/init/template/hana/index.js +3 -2
  98. package/lib/init/template/hana-serverless/files/db/package.json +14 -0
  99. package/lib/init/template/hana-serverless/files/identity.values.yaml.hbs +10 -0
  100. package/lib/init/template/hana-serverless/files/mta.yaml.hbs +64 -0
  101. package/lib/init/template/hana-serverless/files/package.json.hbs +35 -0
  102. package/lib/init/template/hana-serverless/files/src/.hdiconfig +139 -0
  103. package/lib/init/template/hana-serverless/files/undeploy.json +7 -0
  104. package/lib/init/template/hana-serverless/files/values.yaml.hbs +18 -0
  105. package/lib/init/template/hana-serverless/index.js +184 -0
  106. package/lib/init/template/html5-repo/files/containerize.yaml.hbs +2 -2
  107. package/lib/init/template/html5-repo/files/mta.yaml.hbs +5 -0
  108. package/lib/init/template/html5-repo/index.js +18 -14
  109. package/lib/init/template/http/index.js +123 -26
  110. package/lib/init/template/ias/index.js +2 -2
  111. package/lib/init/template/kafka/index.js +2 -2
  112. package/lib/init/template/kyma/index.js +7 -5
  113. package/lib/init/template/malware-scanner/index.js +2 -2
  114. package/lib/init/template/mta/files/mta.yaml.hbs +1 -1
  115. package/lib/init/template/multitenancy/index.js +18 -3
  116. package/lib/init/template/notifications/index.js +2 -2
  117. package/lib/init/template/portal/files/mta.yaml.hbs +4 -0
  118. package/lib/init/template/portal/index.js +13 -8
  119. package/lib/init/template/postgres/index.js +2 -2
  120. package/lib/init/template/redis/index.js +2 -2
  121. package/lib/init/template/sample/files/db/currencies.cds +2 -0
  122. package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Authors.csv +1 -1
  123. package/lib/init/template/tiny-sample/files/nodejs/db/data/CatalogService.Books.csv +2 -2
  124. package/lib/init/template/workzone-standard/index.js +5 -5
  125. package/lib/init/template/xsuaa/index.js +20 -2
  126. package/lib/lint/eslintHelp.json +1 -1
  127. package/lib/mtx/auth_manager.js +103 -37
  128. package/lib/mtx/params.js +3 -2
  129. package/lib/mtx/settings_manager.js +45 -28
  130. package/lib/mtx/tenant_action.js +0 -1
  131. package/lib/mtx/util/credentials.js +62 -0
  132. package/node_modules/@sap/cds/CHANGELOG.md +57 -0
  133. package/node_modules/@sap/cds/app/index.js +5 -4
  134. package/node_modules/@sap/cds/eslint.config.mjs +1 -0
  135. package/node_modules/@sap/cds/lib/compile/minify.js +14 -10
  136. package/node_modules/@sap/cds/lib/env/cds-env.js +1 -1
  137. package/node_modules/@sap/cds/lib/env/cds-requires.js +22 -11
  138. package/node_modules/@sap/cds/lib/env/defaults.js +4 -1
  139. package/node_modules/@sap/cds/lib/env/schemas/cds-rc.js +5 -2
  140. package/node_modules/@sap/cds/lib/plugins.js +9 -5
  141. package/node_modules/@sap/cds/lib/req/spawn.js +1 -1
  142. package/node_modules/@sap/cds/lib/srv/srv-dispatch.js +1 -1
  143. package/node_modules/@sap/cds/lib/srv/srv-models.js +1 -1
  144. package/node_modules/@sap/cds/lib/utils/cds-utils.js +2 -1
  145. package/node_modules/@sap/cds/libx/_runtime/common/generic/assert.js +2 -3
  146. package/node_modules/@sap/cds/libx/_runtime/common/generic/auth/restrict.js +8 -1
  147. package/node_modules/@sap/cds/libx/_runtime/common/generic/crud.js +18 -8
  148. package/node_modules/@sap/cds/libx/_runtime/fiori/lean-draft.js +25 -17
  149. package/node_modules/@sap/cds/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +9 -3
  150. package/node_modules/@sap/cds/libx/_runtime/remote/Service.js +4 -19
  151. package/node_modules/@sap/cds/libx/_runtime/remote/utils/LruCache.js +42 -0
  152. package/node_modules/@sap/cds/libx/_runtime/remote/utils/client.js +14 -4
  153. package/node_modules/@sap/cds/libx/_runtime/remote/utils/cloudSdkProvider.js +2 -9
  154. package/node_modules/@sap/cds/libx/_runtime/remote/utils/destinationClient.js +150 -0
  155. package/node_modules/@sap/cds/libx/_runtime/remote/utils/error.js +13 -0
  156. package/node_modules/@sap/cds/libx/_runtime/remote/utils/fetchClient.js +26 -18
  157. package/node_modules/@sap/cds/libx/_runtime/remote/utils/query.js +34 -23
  158. package/node_modules/@sap/cds/libx/_runtime/remote/utils/token.js +82 -0
  159. package/node_modules/@sap/cds/libx/_runtime/ucl/Service.js +36 -189
  160. package/node_modules/@sap/cds/libx/common/utils/streaming.js +16 -16
  161. package/node_modules/@sap/cds/libx/http/location.js +3 -3
  162. package/node_modules/@sap/cds/libx/odata/middleware/batch.js +16 -10
  163. package/node_modules/@sap/cds/libx/odata/middleware/metadata.js +9 -6
  164. package/node_modules/@sap/cds/libx/odata/middleware/service-document.js +1 -1
  165. package/node_modules/@sap/cds/libx/odata/parse/afterburner.js +19 -3
  166. package/node_modules/@sap/cds/libx/odata/parse/cqn2odata.js +83 -86
  167. package/node_modules/@sap/cds/libx/queue/SchedulingService.js +17 -2
  168. package/node_modules/@sap/cds/libx/queue/processing.js +1 -3
  169. package/node_modules/@sap/cds/libx/rest/RestAdapter.js +3 -7
  170. package/node_modules/@sap/cds/libx/rest/middleware/delete.js +3 -3
  171. package/node_modules/@sap/cds/libx/rest/middleware/parse.js +13 -8
  172. package/node_modules/@sap/cds/libx/rest/middleware/read.js +3 -3
  173. package/node_modules/@sap/cds/libx/rest/middleware/upsert.js +2 -2
  174. package/node_modules/@sap/cds/package.json +1 -1
  175. package/node_modules/@sap/cds-compiler/CHANGELOG.md +60 -8
  176. package/node_modules/@sap/cds-compiler/bin/cdsc.js +2 -2
  177. package/node_modules/@sap/cds-compiler/doc/IncompatibleChanges_v7.md +46 -19
  178. package/node_modules/@sap/cds-compiler/lib/api/main.js +10 -7
  179. package/node_modules/@sap/cds-compiler/lib/api/options.js +8 -2
  180. package/node_modules/@sap/cds-compiler/lib/base/csnRefs.js +5 -2
  181. package/node_modules/@sap/cds-compiler/lib/base/message-registry.js +4 -0
  182. package/node_modules/@sap/cds-compiler/lib/base/optionProcessor.js +12 -0
  183. package/node_modules/@sap/cds-compiler/lib/checks/enricher.js +1 -0
  184. package/node_modules/@sap/cds-compiler/lib/compiler/assert-consistency.js +8 -7
  185. package/node_modules/@sap/cds-compiler/lib/compiler/checks.js +3 -3
  186. package/node_modules/@sap/cds-compiler/lib/compiler/define.js +301 -75
  187. package/node_modules/@sap/cds-compiler/lib/compiler/dictionaries.js +2 -0
  188. package/node_modules/@sap/cds-compiler/lib/compiler/extend.js +40 -26
  189. package/node_modules/@sap/cds-compiler/lib/compiler/populate.js +45 -60
  190. package/node_modules/@sap/cds-compiler/lib/compiler/propagator.js +16 -7
  191. package/node_modules/@sap/cds-compiler/lib/compiler/resolve.js +41 -15
  192. package/node_modules/@sap/cds-compiler/lib/compiler/shared.js +7 -6
  193. package/node_modules/@sap/cds-compiler/lib/compiler/tweak-assocs.js +62 -50
  194. package/node_modules/@sap/cds-compiler/lib/compiler/utils.js +29 -14
  195. package/node_modules/@sap/cds-compiler/lib/edm/edmAnnoPreprocessor.js +6 -5
  196. package/node_modules/@sap/cds-compiler/lib/gen/CdlGrammar.checksum +1 -1
  197. package/node_modules/@sap/cds-compiler/lib/gen/CdlParser.js +1119 -1109
  198. package/node_modules/@sap/cds-compiler/lib/gen/Dictionary.json +19 -3
  199. package/node_modules/@sap/cds-compiler/lib/json/from-csn.js +10 -16
  200. package/node_modules/@sap/cds-compiler/lib/json/to-csn.js +58 -39
  201. package/node_modules/@sap/cds-compiler/lib/main.d.ts +8 -0
  202. package/node_modules/@sap/cds-compiler/lib/main.js +1 -0
  203. package/node_modules/@sap/cds-compiler/lib/model/csnUtils.js +2 -0
  204. package/node_modules/@sap/cds-compiler/lib/parsers/AstBuildingParser.js +2 -1
  205. package/node_modules/@sap/cds-compiler/lib/parsers/XprTree.js +8 -0
  206. package/node_modules/@sap/cds-compiler/lib/render/toCdl.js +22 -1
  207. package/node_modules/@sap/cds-compiler/lib/render/toSql.js +17 -2
  208. package/node_modules/@sap/cds-compiler/lib/render/utils/common.js +6 -1
  209. package/node_modules/@sap/cds-compiler/lib/render/utils/operators.js +27 -0
  210. package/node_modules/@sap/cds-compiler/lib/render/utils/standardDatabaseFunctions.js +125 -3
  211. package/node_modules/@sap/cds-compiler/lib/tool-lib/revealInternalProperties.js +2 -1
  212. package/node_modules/@sap/cds-compiler/lib/transform/db/applyTransformations.js +3 -0
  213. package/node_modules/@sap/cds-compiler/lib/transform/db/associations.js +8 -2
  214. package/node_modules/@sap/cds-compiler/lib/transform/db/backlinks.js +22 -6
  215. package/node_modules/@sap/cds-compiler/lib/transform/db/constraints.js +62 -1
  216. package/node_modules/@sap/cds-compiler/lib/transform/effective/annotations.js +40 -0
  217. package/node_modules/@sap/cds-compiler/lib/transform/effective/main.js +1 -0
  218. package/node_modules/@sap/cds-compiler/lib/transform/forRelationalDB.js +6 -1
  219. package/node_modules/@sap/cds-compiler/lib/transform/translateAssocsToJoins.js +19 -8
  220. package/node_modules/@sap/cds-compiler/package.json +1 -1
  221. package/node_modules/@sap/cds-mtxs/CHANGELOG.md +15 -0
  222. package/node_modules/@sap/cds-mtxs/bin/cds-mtx.js +34 -16
  223. package/node_modules/@sap/cds-mtxs/lib/utils.js +19 -4
  224. package/node_modules/@sap/cds-mtxs/package.json +1 -1
  225. package/node_modules/@sap/cds-mtxs/srv/cf/abstract-provisioning-service.js +1 -1
  226. package/node_modules/@sap/cds-mtxs/srv/extensibility-service.js +22 -13
  227. package/node_modules/@sap/cds-mtxs/srv/model-provider.js +17 -2
  228. package/node_modules/@sap/cds-mtxs/srv/plugins/hana/ctnr-mgr-base.js +1 -1
  229. package/node_modules/@sap/cds-mtxs/srv/plugins/hana.js +4 -8
  230. package/node_modules/@sap/xsenv/CHANGELOG.md +7 -0
  231. package/node_modules/@sap/xsenv/package.json +10 -7
  232. package/node_modules/body-parser/node_modules/content-type/README.md +2 -0
  233. package/node_modules/body-parser/node_modules/content-type/dist/index.d.ts +20 -0
  234. package/node_modules/body-parser/node_modules/content-type/dist/index.js +20 -14
  235. package/node_modules/body-parser/node_modules/content-type/dist/index.js.map +1 -1
  236. package/node_modules/body-parser/node_modules/content-type/package.json +1 -1
  237. package/node_modules/hdb/cfg/VERSION +1 -1
  238. package/node_modules/hdb/lib/protocol/ClientInfo.js +16 -3
  239. package/node_modules/hdb/lib/protocol/Connection.js +1 -0
  240. package/node_modules/hdb/package.json +3 -2
  241. package/node_modules/negotiator/lib/accept.js +54 -0
  242. package/node_modules/negotiator/lib/charset.js +10 -34
  243. package/node_modules/negotiator/lib/encoding.js +9 -30
  244. package/node_modules/negotiator/lib/language.js +15 -36
  245. package/node_modules/negotiator/lib/mediaType.js +16 -134
  246. package/node_modules/negotiator/node_modules/content-type/LICENSE +22 -0
  247. package/node_modules/negotiator/node_modules/content-type/README.md +71 -0
  248. package/node_modules/negotiator/node_modules/content-type/dist/index.d.ts +46 -0
  249. package/node_modules/negotiator/node_modules/content-type/dist/index.js +176 -0
  250. package/node_modules/negotiator/node_modules/content-type/dist/index.js.map +1 -0
  251. package/node_modules/negotiator/node_modules/content-type/package.json +52 -0
  252. package/node_modules/negotiator/package.json +16 -10
  253. package/node_modules/qs/.github/THREAT_MODEL.md +3 -3
  254. package/node_modules/qs/CHANGELOG.md +15 -0
  255. package/node_modules/qs/README.md +19 -1
  256. package/node_modules/qs/dist/qs.js +21 -21
  257. package/node_modules/qs/eslint.config.mjs +1 -1
  258. package/node_modules/qs/lib/parse.js +3 -4
  259. package/node_modules/qs/lib/stringify.js +23 -8
  260. package/node_modules/qs/lib/utils.js +10 -3
  261. package/node_modules/qs/package.json +4 -4
  262. package/node_modules/qs/test/parse.js +192 -3
  263. package/node_modules/qs/test/stringify.js +317 -0
  264. package/node_modules/qs/test/utils.js +12 -0
  265. package/node_modules/type-is/node_modules/content-type/README.md +2 -0
  266. package/node_modules/type-is/node_modules/content-type/dist/index.d.ts +20 -0
  267. package/node_modules/type-is/node_modules/content-type/dist/index.js +20 -14
  268. package/node_modules/type-is/node_modules/content-type/dist/index.js.map +1 -1
  269. package/node_modules/type-is/node_modules/content-type/package.json +1 -1
  270. package/node_modules/ws/lib/permessage-deflate.js +3 -1
  271. package/node_modules/ws/package.json +1 -1
  272. package/package.json +3 -3
  273. package/bin/completion/scripts/cds-bash.sh +0 -20
  274. package/bin/completion/scripts/cds-fish.fish +0 -13
  275. package/bin/completion/scripts/cds-ps.ps1 +0 -19
  276. package/bin/completion/scripts/cds-zsh.sh +0 -13
  277. package/lib/deploy/index.js +0 -25
  278. package/lib/import/asyncapi/importAsyncAPI.js +0 -33
  279. package/lib/import/asyncapi/index.js +0 -18
  280. package/lib/import/asyncapi/parserContext.js +0 -454
  281. package/lib/import/asyncapi/utils.js +0 -49
  282. package/node_modules/@sap/cds/libx/_runtime/ucl/queries.js +0 -61
  283. package/node_modules/negotiator/HISTORY.md +0 -114
  284. /package/{lib → bin}/upgrade/context.js +0 -0
  285. /package/{lib → bin}/upgrade/migrations/cds10/migrations.json +0 -0
  286. /package/{lib → bin}/upgrade/preflight/cds-version.js +0 -0
  287. /package/{lib → bin}/upgrade/preflight/project-type.js +0 -0
  288. /package/{lib → bin}/upgrade/steps/analyze/classification.js +0 -0
  289. /package/{lib → bin}/upgrade/steps/analyze/detector.js +0 -0
  290. /package/{lib → bin}/upgrade/steps/analyze/evaluator.js +0 -0
  291. /package/{lib → bin}/upgrade/steps/analyze/reporter.js +0 -0
  292. /package/{lib → bin}/upgrade/steps/analyze/setup.js +0 -0
  293. /package/{lib → bin}/upgrade/steps/analyze/utils/detection.js +0 -0
  294. /package/{lib → bin}/upgrade/steps/analyze/utils/files.js +0 -0
  295. /package/{lib → bin}/upgrade/steps/analyze/utils/grep.js +0 -0
  296. /package/{lib → bin}/upgrade/steps/analyze/utils/yaml.js +0 -0
  297. /package/{lib → bin}/upgrade/util/workspaces.js +0 -0
  298. /package/{lib → bin}/watch/esm-resolve-registration.js +0 -0
  299. /package/{lib → bin}/watch/livereload-server.js +0 -0
  300. /package/{lib → bin}/watch/node-watch.js +0 -0
  301. /package/{lib → bin}/watch/open.js +0 -0
  302. /package/{lib → bin}/watch/watcher.js +0 -0
@@ -45,8 +45,10 @@ module.exports = class Plugin {
45
45
 
46
46
  /**
47
47
  * Runs the combine operations for interoperability with other plugins.
48
+ * @param {string} [facet] This plugin's facet name, forwarded to `readProject(facet)`
49
+ * so `add<Facet>` accessors can tell whether this facet is the one being added.
48
50
  */
49
- async combine() { }
51
+ async combine(facet) { } // eslint-disable-line no-unused-vars
50
52
 
51
53
 
52
54
  /* ––––––––––––
@@ -65,9 +65,12 @@ module.exports = new class ProjectReader {
65
65
  * Reads the project configuration and constructs a project object.
66
66
  * This function dynamically resolves project properties and returns an object with these properties.
67
67
  *
68
+ * @param {string} [caller] The facet whose `combine()`/`run()` is requesting the project.
69
+ * Used to resolve `add<Facet>` accessors: a template asks "am I being added right now?".
70
+ * Omit when no facet context applies; `add<Facet>` then reflects only the CLI add list.
68
71
  * @returns {ProjectConfig} An object representing the project configuration.
69
72
  */
70
- readProject() {
73
+ readProject(caller) {
71
74
  if (!this.appName) this.#setPackageInfo()
72
75
  const env = this.env4('production')
73
76
  if (this.isJava) env.build.target = '.'
@@ -83,8 +86,17 @@ module.exports = new class ProjectReader {
83
86
  const _uiModule = () => !_uiEmbedded() && isdir(env.folders.app) && fs.readdirSync(resolve(cds.root, env.folders.app)).length > 0
84
87
  const _isJava = () => this.isJava
85
88
  const _extends = () => pkgJson().extends
89
+ const UI_PACKAGES = ['@ui5/cli', 'react', 'vue', 'svelte', '@angular/core', 'vite']
86
90
  const isApp = name => {
87
- return name !== 'appconfig' && !name.match(/^[._]/) && name !== 'router' && name !== 'portal' && name !== 'workzone' && name !== 'html5-deployer'
91
+ if (name.match(/^[._]/)) return false
92
+ const dir = path.join(cds.root, cds.env.folders.app, name)
93
+ if (exists(path.join(dir, 'webapp/manifest.json'))) return true
94
+ if (exists(path.join(dir, 'index.html'))) return true
95
+ const pJsonPath = path.join(dir, 'package.json')
96
+ if (!exists(pJsonPath)) return false
97
+ const { dependencies, devDependencies } = JSON.parse(fs.readFileSync(pJsonPath))
98
+ const deps = { ...dependencies, ...devDependencies }
99
+ return UI_PACKAGES.some(p => p in deps)
88
100
  }
89
101
  const reserved = {
90
102
  dependencies: () => pkgJson().dependencies,
@@ -129,6 +141,9 @@ module.exports = new class ProjectReader {
129
141
  const inbounds = manifest?.['sap.app']?.crossNavigation?.inbounds
130
142
  const [firstInbound] = Object.values(inbounds ?? { intent: { semanticObject: 'Books', action: 'display' } })
131
143
  const vizId = firstInbound.semanticObject + '-' + firstInbound.action
144
+ const appPkgPath = path.resolve(cds.root, cds.env.folders.app, app, 'package.json')
145
+ const appPkg = exists(appPkgPath) ? JSON.parse(fs.readFileSync(appPkgPath, 'utf-8')) : {}
146
+ const isStatic = !appPkg.scripts?.build
132
147
  // Try to read archiveName from ui5.yaml if it exists
133
148
  let archiveName = ''
134
149
  const ui5YamlPaths = [
@@ -145,7 +160,7 @@ module.exports = new class ProjectReader {
145
160
  }
146
161
  }
147
162
  }
148
- return { app, strippedApp: app.replace(/-/g, ''), vizId, isNotLast: i < apps.length - 1, manifestAppId: manifest?.['sap.app']?.id ?? app, archiveName }
163
+ return { app, strippedApp: app.replace(/-/g, ''), vizId, isNotLast: i < apps.length - 1, manifestAppId: manifest?.['sap.app']?.id ?? app, archiveName, isStatic }
149
164
  })
150
165
  },
151
166
  appUIPaths: () => {
@@ -159,7 +174,8 @@ module.exports = new class ProjectReader {
159
174
  appPath: () => env.folders.app,
160
175
  appVersion: () => appVersion,
161
176
  jdkVersion: () => jdkVersion,
162
- approuterPath: () => (_uiEmbedded() ? join(env.folders.app) : exists('.deploy/app-router') ? join('.deploy', 'app-router') : join(env.folders.app, 'router')).replace(/\\/g, '/'),
177
+ approuterPath: () => (_uiEmbedded() ? join(env.folders.app) : exists(join(env.folders.app, 'router')) ? join(env.folders.app, 'router') : join('.deploy', 'app-router')).replace(/\\/g, '/'),
178
+ html5DeployerPath: () => (exists(join(env.folders.app, 'html5-deployer')) ? join(env.folders.app, 'html5-deployer') : join('.deploy', 'html5-deployer')).replace(/\\/g, '/'),
163
179
  appName: () => appName,
164
180
  cleanedAppName: () => appName.replaceAll('_', '-'),
165
181
  strippedAppName: () => appName.replace(/-/g, ''),
@@ -221,8 +237,7 @@ module.exports = new class ProjectReader {
221
237
  const inProd = _inProd(facet)
222
238
  if (prefix === 'add') {
223
239
  const adding = plugin => cds.cli.command === 'add' && cds.cli.argv[0]?.split(',').includes(plugin) || cds.cli.options.add?.has(plugin)
224
- const caller = new Error().stack.split('\n')[3].replace(/\\/g, '/').match(/lib\/init\/template\/([^/]+)\/index\.js/)[1]
225
- return inProd && (adding(facet) || adding(caller))
240
+ return inProd && (adding(facet) || (caller && adding(caller)))
226
241
  }
227
242
  return inProd
228
243
  }
@@ -304,6 +319,7 @@ function _normalizeSpringBootCfg(obj) {
304
319
  * @property {string} configFile The name of the configuration file. This is typically the `package.json` for Node.js and `.cdsrc.json` for Java.
305
320
  * @property {string} appPath The path to the app folder.
306
321
  * @property {string} approuterPath The path to the approuter folder.
322
+ * @property {string} html5DeployerPath The path to the HTML5 application content deployer folder.
307
323
  * @property {boolean} hasUIEmbedded Indicates if the project uses an embedded UI.
308
324
  * @property {boolean} hasUIModule Indicates if the project is using a modular UI.
309
325
  * @property {boolean} hasUI Indicates if the project has a UI.
@@ -1,8 +1,6 @@
1
-
2
-
3
- const odataApi = {
1
+ const srvApi = {
4
2
  in: 'routes',
5
- where: { target: '/odata/$1' }
3
+ where: { destination: 'srv-api' }
6
4
  }
7
5
 
8
6
  const html5RepoApi = {
@@ -11,6 +9,6 @@ const html5RepoApi = {
11
9
  }
12
10
 
13
11
  module.exports = {
14
- odataApi,
12
+ srvApi,
15
13
  html5RepoApi
16
14
  }
@@ -11,4 +11,4 @@ resources:
11
11
  type: org.cloudfoundry.managed-service
12
12
  parameters:
13
13
  service: aicore
14
- service-plan: standard
14
+ service-plan: {{#servicePlan}}{{servicePlan}}{{/servicePlan}}{{^servicePlan}}standard{{/servicePlan}}
@@ -1,3 +1,4 @@
1
+ const cds = require('../../../cds')
1
2
  const { readProject } = require('../../projectReader')
2
3
  const { merge } = require('../../merge')
3
4
  const { srv4, aicore } = require('../../registries/mta')
@@ -9,6 +10,15 @@ module.exports = class AiTemplate extends require('../../plugin') {
9
10
  return 'SAP BTP AI Core'
10
11
  }
11
12
 
13
+ options() {
14
+ return {
15
+ 'plan': {
16
+ type: 'string',
17
+ help: 'Specify the service plan.',
18
+ }
19
+ }
20
+ }
21
+
12
22
  static hasInProduction(env) {
13
23
  const { dependencies, isJava } = readProject()
14
24
  return dependencies?.['@cap-js/ai'] || isJava && env.requires?.AICore
@@ -20,11 +30,13 @@ module.exports = class AiTemplate extends require('../../plugin') {
20
30
  await merge(__dirname, 'files/package.json.hbs').into(configFile, { project })
21
31
  }
22
32
 
23
- async combine() {
24
- const project = readProject()
33
+ async combine(facet) {
34
+ const project = readProject(facet)
25
35
  const { addMta, addKyma, addMultitenancy, srv } = project
36
+ const { plan } = cds.cli.options
26
37
 
27
38
  if (addMta) {
39
+ if (plan) project.servicePlan = plan
28
40
  const srvModule = srv4(srv.path)
29
41
  await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', {
30
42
  with: project,
@@ -26,8 +26,8 @@ module.exports = class AmsTemplate extends require('../../plugin') {
26
26
  if (project.isJava) await mvn.add('ams')
27
27
  }
28
28
 
29
- async combine() {
30
- const project = readProject()
29
+ async combine(facet) {
30
+ const project = readProject(facet)
31
31
  const { addMta, addCfManifest, addKyma } = project
32
32
 
33
33
  if (addMta) {
@@ -7,7 +7,7 @@ modules:
7
7
  builder: proxy-unified-runtime-dmz.int.repositories.cloud.sap/builder/noble
8
8
  {{/hasKymaUnifiedRuntime}}
9
9
  {{^hasKymaUnifiedRuntime}}
10
- type: sapse/application-content-deployer-buildpack:1.4.0
10
+ type: sapse/application-content-deployer-buildpack:1.5.0
11
11
  builder: builder-jammy-base
12
12
  {{/hasKymaUnifiedRuntime}}
13
- path: app/html5-deployer
13
+ path: {{& html5DeployerPath}}
@@ -1,7 +1,7 @@
1
1
  const { readProject } = require('../../projectReader')
2
2
  const { merge } = require('../../merge')
3
3
  const { srv4, appDeployer, appFront, xsuaa } = require('../../registries/mta')
4
- const { odataApi } = require('../../registries/xs-app')
4
+ const { srvApi } = require('../../registries/xs-app')
5
5
  const { renderAndCopy } = require('../../template')
6
6
  const { sh:$, path:{join}, fs:{promises:{rename}}, write, read, exists } = require('../../../cds').utils
7
7
 
@@ -50,8 +50,8 @@ module.exports = class extends require('../../plugin') {
50
50
 
51
51
  }
52
52
 
53
- async combine() {
54
- const project = readProject()
53
+ async combine(facet) {
54
+ const project = readProject(facet)
55
55
  const {
56
56
  srv, appPath, apps,
57
57
  hasMta, addMta, hasXsuaa, addSample, addApprouter, addWorkzoneStandard, addXsuaa, addIas,
@@ -61,7 +61,7 @@ module.exports = class extends require('../../plugin') {
61
61
  await Promise.all(apps.map(async ({ app }) => {
62
62
  project.app = app
63
63
  project.hasIndexHtml = exists(join(appPath, app, 'webapp/index.html'))
64
- const additions = [odataApi]
64
+ const additions = [srvApi]
65
65
  await merge(__dirname, 'files/xs-app.json.hbs').into(join(appPath, app, 'xs-app.json'), { with: project, additions })
66
66
  }))
67
67
 
@@ -26,8 +26,8 @@ module.exports = class ApplicationLoggingTemplate extends require('../../plugin'
26
26
  if (isJava) await mvn.add('APPLICATION_LOGGING')
27
27
  }
28
28
 
29
- async combine() {
30
- const project = readProject()
29
+ async combine(facet) {
30
+ const project = readProject(facet)
31
31
  const { addMta, hasMta, hasApprouter, isJava, addMultitenancy, hasMultitenancy, srv } = project
32
32
 
33
33
  if (addMta || (addMultitenancy && hasMta)) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "approuter",
3
3
  "dependencies": {
4
- "@sap/approuter": "^22.0.0"
4
+ "@sap/approuter": "^23.0.0"
5
5
  },
6
6
  "scripts": {
7
7
  "start": "node node_modules/@sap/approuter/approuter.js"
@@ -31,8 +31,8 @@ module.exports = class ApprouterTemplate extends require('../../plugin') {
31
31
  await merge(__dirname, 'files/default-env.json').into(approuterPath + '/default-env.json')
32
32
  }
33
33
 
34
- async combine() {
35
- const project = readProject()
34
+ async combine(facet) {
35
+ const project = readProject(facet)
36
36
  const {
37
37
  isNodejs, isJava,
38
38
  addIas, addXsuaa, hasXsuaa, hasIas, addMultitenancy, hasMTXRoute, hasMTXRouteJava,
@@ -51,6 +51,7 @@ module.exports = class ApprouterTemplate extends require('../../plugin') {
51
51
  if (hasMultitenancy) modules.push(mtxSidecar)
52
52
  const additions = [...modules, ...apis]
53
53
  const relationships = []
54
+ const deletions = []
54
55
  if (hasXsuaa) {
55
56
  relationships.push({
56
57
  insert: [xsuaa, 'name'],
@@ -62,9 +63,13 @@ module.exports = class ApprouterTemplate extends require('../../plugin') {
62
63
  insert: [ias, 'name'],
63
64
  into: [approuter, 'requires', 'name']
64
65
  })
66
+ deletions.push({
67
+ item: { in: [approuter, 'requires'], where: { 'name': 'srv-api' } },
68
+ key: 'properties.name'
69
+ })
65
70
  }
66
71
  await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', {
67
- with: project, additions, relationships,
72
+ with: project, additions, relationships, deletions,
68
73
  })
69
74
  }
70
75
 
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "dependencies": {
3
- "@cap-js/attachments": "^3"
3
+ "@cap-js/attachments": "^4"
4
4
  }
5
5
  }
@@ -25,8 +25,8 @@ module.exports = class AttachmentsTemplate extends require('../../plugin') {
25
25
  if (isJava) await mvn.add('attachments')
26
26
  }
27
27
 
28
- async combine() {
29
- const project = readProject()
28
+ async combine(facet) {
29
+ const project = readProject(facet)
30
30
  const { addMta, addKyma, srv } = project
31
31
 
32
32
  if (addMta) {
@@ -32,8 +32,8 @@ module.exports = class AuditLoggingTemplate extends require('../../plugin') {
32
32
  if (isJava) await mvn.add('audit_logging')
33
33
  }
34
34
 
35
- async combine() {
36
- const project = readProject()
35
+ async combine(facet) {
36
+ const project = readProject(facet)
37
37
  const { addMta, addKyma, addMultitenancy, srv } = project
38
38
  const { plan = 'premium' } = cds.cli.options
39
39
  project.servicePlan = plan
@@ -1,11 +1,11 @@
1
1
  {
2
2
  {{#withTelemetry}}
3
3
  "dependencies": {
4
- "@cap-js/telemetry": ">=0",
4
+ "@cap-js/telemetry": "^2",
5
5
  "@grpc/grpc-js": "^1",
6
- "@opentelemetry/exporter-trace-otlp-grpc": "<0.200",
7
- "@opentelemetry/exporter-metrics-otlp-grpc": "<0.200",
8
- "@opentelemetry/host-metrics": "<0.200"
6
+ "@opentelemetry/exporter-trace-otlp-grpc": ">=0.200",
7
+ "@opentelemetry/exporter-metrics-otlp-grpc": ">=0.200",
8
+ "@opentelemetry/instrumentation-host-metrics": ">=0.2"
9
9
  },
10
10
  {{/withTelemetry}}
11
11
  "cds": {
@@ -38,8 +38,8 @@ module.exports = class extends require('../../plugin') {
38
38
  }
39
39
  }
40
40
 
41
- async combine() {
42
- const project = readProject()
41
+ async combine(facet) {
42
+ const project = readProject(facet)
43
43
  const { hasMta, addMta, addKyma, addApprouter, isJava, addMultitenancy, srv } = project
44
44
 
45
45
  if (addMta || (addMultitenancy || addApprouter) && hasMta) {
@@ -16,26 +16,33 @@ const SUPPORTED_SHELLS = [...SUPPORTED_LINUX_SHELLS, ...SUPPORTED_WINDOWS_SHELLS
16
16
  module.exports = new class CompletionSetup {
17
17
  supportedShells = SUPPORTED_SHELLS
18
18
 
19
- async setup(addEntry, options) {
20
- const shell = options.shell
19
+ resolveShell(options) {
20
+ return options?.shell
21
21
  || (process.env.MSYSTEM?.includes('MINGW64') ? 'gitbash' : process.env.SHELL?.match(/(bash|fish|zsh)/)?.[0])
22
22
  || (process.env.PSModulePath ? 'ps' : null);
23
+ }
24
+
25
+ async setup(addEntry, options) {
26
+ const shell = this.resolveShell(options);
23
27
 
24
28
  switch (shell) {
25
29
  case 'bash':
26
30
  case 'fish':
27
31
  case 'gitbash':
28
32
  case 'zsh':
29
- return this.setupLinuxLike(addEntry, shell);
33
+ await this.setupLinuxLike(addEntry, shell);
34
+ return shell;
30
35
  case 'ps':
31
- return this.setupPs(addEntry);
36
+ await this.setupPs(addEntry);
37
+ return shell;
32
38
  case null:
33
39
  try {
34
40
  const shellType = this.determineShellLinux();
35
41
  if (!shellType) {
36
42
  throw `Unsupported shell.\nSupported shells are: ${SUPPORTED_SHELLS.join(', ')}.`;
37
43
  }
38
- return this.setupLinuxLike(addEntry, shellType);
44
+ await this.setupLinuxLike(addEntry, shellType);
45
+ return shellType;
39
46
  } catch (err) {
40
47
  throw `Error during completion setup: ${err}`;
41
48
  }
@@ -95,7 +102,7 @@ module.exports = new class CompletionSetup {
95
102
 
96
103
  profileFile = path.join(os.homedir(), profileFile);
97
104
 
98
- await this.changeProfile(profileFile, shell, addEntry);
105
+ await this.changeProfile(profileFile, shell, addEntry, this.resolveScriptPath(shell));
99
106
 
100
107
  const relProfilePath = path.relative(os.homedir(), profileFile);
101
108
  console.log(`\nSource your shell using\n${bold(`source ~/${relProfilePath}`)}\nto activate the changes.\n`);
@@ -113,55 +120,45 @@ module.exports = new class CompletionSetup {
113
120
  throw err;
114
121
  }
115
122
 
116
- await this.changeProfile(profilePath, 'ps', addEntry);
123
+ await this.changeProfile(profilePath, 'ps', addEntry, this.resolveScriptPath('ps'));
117
124
  console.log(`\nSource your shell using\n${bold('. $PROFILE')}\nto activate the changes.`);
118
125
  }
119
126
 
120
- getScript(shell) {
127
+ // Returns the absolute path to the pre-generated cache file bundled with this package.
128
+ resolveScriptPath(shell) {
129
+ const cacheFiles = { bash: 'cds.sh', gitbash: 'cds.sh', fish: 'cds.fish', ps: 'cds.ps1', zsh: 'cds.zsh' };
130
+ return path.join(__dirname, '../../../../bin/completion/scripts', cacheFiles[shell]);
131
+ }
132
+
133
+ // Generates the snippet written to the user's shell profile. The script path is hardcoded at
134
+ // install time to avoid spawning a subprocess on every shell startup.
135
+ getScript(shell, scriptPath) {
121
136
  switch (shell) {
122
137
  case 'bash':
123
138
  case 'gitbash':
124
- return `
125
- CDS_PROFILE=$(cds completion --shell ${shell} --profile 2> /dev/null) || CDS_PROFILE=""
126
- if [ -r "$CDS_PROFILE" ]; then
127
- . "$CDS_PROFILE"
128
- fi
129
- `
139
+ return `# cds shell completion script (path resolved at install time)
140
+ _p="${scriptPath}" && [ -r "$_p" ] && . "$_p"`
130
141
  case 'fish':
131
- return `
142
+ return `# cds shell completion script (path resolved at install time)
132
143
  if type "cds" >/dev/null 2>&1
133
- set -l CDS_PROFILE (cds completion --shell fish --profile 2> /dev/null)
134
- if test -e "$CDS_PROFILE"
135
- source "$CDS_PROFILE"
136
- end
137
- end
138
- `
144
+ set -l _p "${scriptPath}"
145
+ test -r "$_p" && source "$_p"
146
+ end`
139
147
  case 'ps':
140
- return `
141
- try {
142
- $CDS_PROFILE = cds completion --shell ps --profile 2> $null
143
- if (Test-Path -Path "$CDS_PROFILE" -PathType Leaf) {
144
- . "$CDS_PROFILE"
145
- }
146
- } catch {}
147
- `
148
-
148
+ return `# cds shell completion script (path resolved at install time)
149
+ $_p = "${scriptPath}"; if (Test-Path -Path "$_p" -PathType Leaf) { . "$_p" }`
149
150
  case 'zsh':
150
- return `
151
- # compinit can be removed here if loaded elsewhere in the script
151
+ return `# compinit can be removed here if loaded elsewhere in the script
152
152
  autoload -Uz compinit && compinit
153
153
 
154
- CDS_PROFILE=$(cds completion --shell zsh --profile 2> /dev/null) || CDS_PROFILE=""
155
- if [ -r "$CDS_PROFILE" ]; then
156
- . "$CDS_PROFILE"
157
- fi
158
- `
154
+ # cds shell completion script (path resolved at install time)
155
+ _p="${scriptPath}" && [ -r "$_p" ] && \\. "$_p"`
159
156
  default:
160
157
  throw `Unsupported shell: ${shell}`;
161
158
  }
162
159
  }
163
160
 
164
- async changeProfile(profileFile, shell, addEntry) {
161
+ async changeProfile(profileFile, shell, addEntry, scriptPath) {
165
162
  let profile = '';
166
163
  let profileFileExists = true;
167
164
  try {
@@ -181,7 +178,7 @@ fi
181
178
  profile = profile + `
182
179
 
183
180
  # cds completion start
184
- ${this.getScript(shell)}
181
+ ${this.getScript(shell, scriptPath)}
185
182
  # cds completion end`;
186
183
  changed = true;
187
184
  }
@@ -18,8 +18,8 @@ module.exports = class ConnectivityTemplate extends require('../../plugin') {
18
18
  await merge(__dirname, 'files', 'package.json.hbs').into(configFile, { with: project })
19
19
  }
20
20
 
21
- async combine() {
22
- const project = readProject()
21
+ async combine(facet) {
22
+ const project = readProject(facet)
23
23
  const { srv, addKyma, addMta } = project
24
24
 
25
25
  if (addMta) {
@@ -4,10 +4,10 @@ const { elementsSorter } = require('./as-json')
4
4
  * Serializes the given JSON data to CSV format
5
5
  * @param {object} data JSON data to serialize
6
6
  * @param {object} csn the model
7
- * @param {{ headerOnly: boolean, separator: boolean }} options
7
+ * @param {{ headerOnly: boolean, keysOnly: boolean, separator: boolean }} options
8
8
  * @returns {Promise<string>} CSV string
9
9
  */
10
- module.exports = async (data={}, csn, { headerOnly=false, separator=',' }={}) => {
10
+ module.exports = async (data={}, csn, { headerOnly=false, keysOnly=false, separator=',' }={}) => {
11
11
 
12
12
  // We might need multiple passes if data for associations/compositions is created on the fly.
13
13
  // So loop as long as there is some non-string data left.
@@ -32,6 +32,15 @@ module.exports = async (data={}, csn, { headerOnly=false, separator=',' }={}) =>
32
32
  if (data[t] === undefined) {
33
33
  data[t] = value // Add object for a new entity. Next pass will process it.
34
34
  }
35
+ // managed to-one composition: emit the foreign-key column(s) on the parent, like an association
36
+ if (!element.on && element.keys) {
37
+ const targetRecord = Array.isArray(value) ? value[0] : value
38
+ const fk = {}
39
+ if (targetRecord) for (const k of element.keys) fk[k.ref[k.ref.length - 1]] = targetRecord[k.ref[k.ref.length - 1]]
40
+ const {headers: fkHeaders, records: fkRecords} = resolveStruct(fk, name)
41
+ if (i === 0) header.push(...fkHeaders)
42
+ record.push(...(keysOnly && !element.key ? fkRecords.map(() => '') : fkRecords))
43
+ }
35
44
  }
36
45
  else if (element._type === 'cds.Association') {
37
46
  if (element.on) {
@@ -42,18 +51,19 @@ module.exports = async (data={}, csn, { headerOnly=false, separator=',' }={}) =>
42
51
  if (i === 0) {
43
52
  header.push(...fkHeaders)
44
53
  }
45
- record.push(...fkRecords)
54
+ // foreign keys of key associations are part of the primary key and must be kept
55
+ record.push(...(keysOnly && !element.key ? fkRecords.map(() => '') : fkRecords))
46
56
  }
47
57
  else if (element.is_struct && element.type !== 'cds.Map') {
48
58
  const {headers: structHeaders, records: structRecords} = resolveStruct(value, name);
49
59
  if (i === 0) {
50
60
  header.push(...structHeaders)
51
61
  }
52
- record.push(...structRecords)
62
+ record.push(...(keysOnly && !element.key ? structRecords.map(() => '') : structRecords))
53
63
  }
54
64
  else {
55
65
  if (i === 0) header.push(name)
56
- record.push(processValue(value))
66
+ record.push(keysOnly && !element.key ? '' : processValue(value))
57
67
  }
58
68
  }
59
69
  records.push(record.join(separator))