@sap/cds-dk 10.0.7 → 10.1.1

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 (341) hide show
  1. package/CHANGELOG.md +106 -0
  2. package/bin/add.js +7 -23
  3. package/bin/bind.js +14 -0
  4. package/bin/build.js +21 -34
  5. package/bin/cds.js +1 -1
  6. package/bin/compile/index.js +16 -41
  7. package/bin/completion/completionFs.js +11 -8
  8. package/bin/completion/index.js +603 -80
  9. package/bin/completion/scripts/cds.fish +620 -0
  10. package/bin/completion/scripts/cds.ps1 +403 -0
  11. package/bin/completion/scripts/cds.sh +327 -0
  12. package/bin/completion/scripts/cds.zsh +296 -0
  13. package/bin/completion/templates/cds-tmpl.fish +65 -0
  14. package/bin/completion/templates/cds-tmpl.ps1 +217 -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 +11 -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/env.js +4 -1
  25. package/bin/export.js +44 -6
  26. package/bin/help/export.md +3 -0
  27. package/bin/help.js +1 -5
  28. package/bin/import.js +9 -0
  29. package/bin/init.js +6 -24
  30. package/bin/inspect.js +8 -0
  31. package/bin/lint.js +5 -3
  32. package/bin/login.js +26 -20
  33. package/bin/minify.js +6 -1
  34. package/bin/pull.js +19 -6
  35. package/bin/push.js +19 -6
  36. package/bin/repl.js +11 -2
  37. package/bin/run.js +12 -1
  38. package/bin/serve.js +13 -2
  39. package/bin/up.js +17 -11
  40. package/{lib → bin}/upgrade/constants.js +1 -1
  41. package/bin/{upgrade.js → upgrade/index.js} +2 -2
  42. package/{lib → bin}/upgrade/preflight/consistency.js +1 -1
  43. package/{lib → bin}/upgrade/preflight/index.js +1 -1
  44. package/{lib → bin}/upgrade/steps/analyze/index.js +1 -1
  45. package/{lib → bin}/upgrade/steps/install.js +1 -1
  46. package/{lib → bin}/upgrade/steps/openrewrite.js +1 -1
  47. package/{lib → bin}/upgrade/steps/removals.js +1 -1
  48. package/{lib → bin}/upgrade/steps/rewrite.js +1 -1
  49. package/{lib → bin}/upgrade/steps/verify.js +1 -1
  50. package/{lib/upgrade/index.js → bin/upgrade/upgrade.js} +2 -2
  51. package/{lib → bin}/upgrade/util/pom.js +2 -2
  52. package/{lib → bin}/upgrade/util/prompt.js +1 -1
  53. package/bin/util/containerize.js +10 -4
  54. package/bin/version.js +10 -1
  55. package/{lib → bin}/watch/hot-reload.js +1 -1
  56. package/bin/{watch.js → watch/index.js} +24 -9
  57. package/{lib → bin}/watch/livereload-connect.js +1 -1
  58. package/{lib → bin}/watch/vite-watch.js +1 -1
  59. package/{lib → bin}/watch/watched.js +2 -2
  60. package/lib/build/constants.js +1 -1
  61. package/lib/build/plugins/fiori/index.js +31 -2
  62. package/lib/build/plugins/internal.js +4 -2
  63. package/lib/build/plugins/mtx-sidecar/index.js +7 -8
  64. package/lib/build/plugins/nodejs/index.js +64 -7
  65. package/lib/build/util.js +2 -4
  66. package/lib/compile/to_asyncapi.js +1 -1
  67. package/lib/env/schema.js +16 -0
  68. package/lib/env/schemas/cds-rc.js +1 -76
  69. package/lib/import/importapi.js +2 -3
  70. package/lib/import/message.js +0 -2
  71. package/lib/init/constants.js +2 -1
  72. package/lib/init/index.js +2 -2
  73. package/lib/init/merge.js +123 -280
  74. package/lib/init/plugin.js +3 -1
  75. package/lib/init/projectReader.js +22 -6
  76. package/lib/init/registries/xs-app.js +3 -5
  77. package/lib/init/template/ai/files/mta.yaml.hbs +1 -1
  78. package/lib/init/template/ai/index.js +14 -2
  79. package/lib/init/template/ams/index.js +2 -2
  80. package/lib/init/template/app-frontend/files/containerize.yaml.hbs +2 -2
  81. package/lib/init/template/app-frontend/index.js +4 -4
  82. package/lib/init/template/application-logging/index.js +2 -2
  83. package/lib/init/template/approuter/files/package.json +1 -1
  84. package/lib/init/template/approuter/index.js +8 -3
  85. package/lib/init/template/attachments/files/package.json.hbs +1 -1
  86. package/lib/init/template/attachments/index.js +2 -2
  87. package/lib/init/template/audit-logging/index.js +2 -2
  88. package/lib/init/template/cloud-logging/files/package.json.hbs +4 -4
  89. package/lib/init/template/cloud-logging/index.js +2 -2
  90. package/lib/init/template/completion/completionSetup.js +36 -39
  91. package/lib/init/template/connectivity/index.js +2 -2
  92. package/lib/init/template/data/as-csv.js +15 -5
  93. package/lib/init/template/data/as-json.js +117 -42
  94. package/lib/init/template/data/index.js +16 -2
  95. package/lib/init/template/destination/index.js +2 -2
  96. package/lib/init/template/dynatrace/files/package.json.hbs +3 -3
  97. package/lib/init/template/dynatrace/index.js +2 -2
  98. package/lib/init/template/enterprise-messaging/index.js +2 -2
  99. package/lib/init/template/enterprise-messaging-shared/index.js +2 -2
  100. package/lib/init/template/extensibility/files/mta.yaml.hbs +11 -0
  101. package/lib/init/template/extensibility/files/xs-security.json.hbs +1 -1
  102. package/lib/init/template/extensibility/index.js +3 -3
  103. package/lib/init/template/github-actions/index.js +2 -2
  104. package/lib/init/template/hana/index.js +3 -2
  105. package/lib/init/template/hana-serverless/files/db/package.json +14 -0
  106. package/lib/init/template/hana-serverless/files/identity.values.yaml.hbs +10 -0
  107. package/lib/init/template/hana-serverless/files/mta.yaml.hbs +64 -0
  108. package/lib/init/template/hana-serverless/files/package.json.hbs +35 -0
  109. package/lib/init/template/hana-serverless/files/src/.hdiconfig +139 -0
  110. package/lib/init/template/hana-serverless/files/undeploy.json +7 -0
  111. package/lib/init/template/hana-serverless/files/values.yaml.hbs +18 -0
  112. package/lib/init/template/hana-serverless/index.js +184 -0
  113. package/lib/init/template/html5-repo/files/containerize.yaml.hbs +2 -2
  114. package/lib/init/template/html5-repo/files/mta.yaml.hbs +5 -0
  115. package/lib/init/template/html5-repo/index.js +18 -14
  116. package/lib/init/template/http/index.js +123 -26
  117. package/lib/init/template/ias/index.js +2 -2
  118. package/lib/init/template/kafka/index.js +2 -2
  119. package/lib/init/template/kyma/index.js +7 -5
  120. package/lib/init/template/malware-scanner/index.js +2 -2
  121. package/lib/init/template/mta/files/mta.yaml.hbs +1 -1
  122. package/lib/init/template/multitenancy/index.js +18 -3
  123. package/lib/init/template/notifications/index.js +2 -2
  124. package/lib/init/template/portal/files/mta.yaml.hbs +4 -0
  125. package/lib/init/template/portal/index.js +13 -8
  126. package/lib/init/template/postgres/index.js +2 -2
  127. package/lib/init/template/redis/index.js +2 -2
  128. package/lib/init/template/sample/files/db/currencies.cds +2 -0
  129. package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Authors.csv +1 -1
  130. package/lib/init/template/tiny-sample/files/nodejs/db/data/CatalogService.Books.csv +2 -2
  131. package/lib/init/template/workzone-standard/index.js +5 -5
  132. package/lib/init/template/xsuaa/index.js +20 -2
  133. package/lib/lint/eslintHelp.json +1 -1
  134. package/lib/mtx/auth_manager.js +103 -37
  135. package/lib/mtx/params.js +3 -2
  136. package/lib/mtx/settings_manager.js +45 -28
  137. package/lib/mtx/tenant_action.js +0 -1
  138. package/lib/mtx/util/credentials.js +62 -0
  139. package/node_modules/@cap-js/db-service/CHANGELOG.md +17 -0
  140. package/node_modules/@cap-js/db-service/lib/common/generic-pool.js +4 -7
  141. package/node_modules/@cap-js/db-service/lib/cqn2pql.js +1 -1
  142. package/node_modules/@cap-js/db-service/lib/cqn2sql.js +15 -11
  143. package/node_modules/@cap-js/db-service/lib/cqn4sql.js +119 -19
  144. package/node_modules/@cap-js/db-service/lib/infer/index.js +27 -16
  145. package/node_modules/@cap-js/db-service/lib/recursion-guard.js +40 -0
  146. package/node_modules/@cap-js/db-service/lib/search.js +1 -1
  147. package/node_modules/@cap-js/db-service/package.json +1 -1
  148. package/node_modules/@cap-js/sqlite/CHANGELOG.md +19 -0
  149. package/node_modules/@cap-js/sqlite/lib/SQLiteService.js +110 -14
  150. package/node_modules/@cap-js/sqlite/package.json +3 -3
  151. package/node_modules/@sap/cds/CHANGELOG.md +57 -0
  152. package/node_modules/@sap/cds/app/index.js +5 -4
  153. package/node_modules/@sap/cds/eslint.config.mjs +1 -0
  154. package/node_modules/@sap/cds/lib/compile/minify.js +14 -10
  155. package/node_modules/@sap/cds/lib/env/cds-env.js +1 -1
  156. package/node_modules/@sap/cds/lib/env/cds-requires.js +22 -11
  157. package/node_modules/@sap/cds/lib/env/defaults.js +4 -1
  158. package/node_modules/@sap/cds/lib/env/schemas/cds-rc.js +5 -2
  159. package/node_modules/@sap/cds/lib/plugins.js +9 -5
  160. package/node_modules/@sap/cds/lib/req/spawn.js +1 -1
  161. package/node_modules/@sap/cds/lib/srv/srv-dispatch.js +1 -1
  162. package/node_modules/@sap/cds/lib/srv/srv-models.js +1 -1
  163. package/node_modules/@sap/cds/lib/utils/cds-utils.js +2 -1
  164. package/node_modules/@sap/cds/libx/_runtime/common/generic/assert.js +2 -3
  165. package/node_modules/@sap/cds/libx/_runtime/common/generic/auth/restrict.js +8 -1
  166. package/node_modules/@sap/cds/libx/_runtime/common/generic/crud.js +18 -8
  167. package/node_modules/@sap/cds/libx/_runtime/fiori/lean-draft.js +25 -17
  168. package/node_modules/@sap/cds/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +9 -3
  169. package/node_modules/@sap/cds/libx/_runtime/remote/Service.js +4 -19
  170. package/node_modules/@sap/cds/libx/_runtime/remote/utils/LruCache.js +42 -0
  171. package/node_modules/@sap/cds/libx/_runtime/remote/utils/client.js +14 -4
  172. package/node_modules/@sap/cds/libx/_runtime/remote/utils/cloudSdkProvider.js +2 -9
  173. package/node_modules/@sap/cds/libx/_runtime/remote/utils/destinationClient.js +150 -0
  174. package/node_modules/@sap/cds/libx/_runtime/remote/utils/error.js +13 -0
  175. package/node_modules/@sap/cds/libx/_runtime/remote/utils/fetchClient.js +26 -18
  176. package/node_modules/@sap/cds/libx/_runtime/remote/utils/query.js +34 -23
  177. package/node_modules/@sap/cds/libx/_runtime/remote/utils/token.js +82 -0
  178. package/node_modules/@sap/cds/libx/_runtime/ucl/Service.js +36 -189
  179. package/node_modules/@sap/cds/libx/common/utils/streaming.js +16 -16
  180. package/node_modules/@sap/cds/libx/http/location.js +3 -3
  181. package/node_modules/@sap/cds/libx/odata/middleware/batch.js +16 -10
  182. package/node_modules/@sap/cds/libx/odata/middleware/metadata.js +9 -6
  183. package/node_modules/@sap/cds/libx/odata/middleware/service-document.js +1 -1
  184. package/node_modules/@sap/cds/libx/odata/parse/afterburner.js +19 -3
  185. package/node_modules/@sap/cds/libx/odata/parse/cqn2odata.js +83 -86
  186. package/node_modules/@sap/cds/libx/queue/SchedulingService.js +17 -2
  187. package/node_modules/@sap/cds/libx/queue/processing.js +1 -3
  188. package/node_modules/@sap/cds/libx/rest/RestAdapter.js +3 -7
  189. package/node_modules/@sap/cds/libx/rest/middleware/delete.js +3 -3
  190. package/node_modules/@sap/cds/libx/rest/middleware/parse.js +13 -8
  191. package/node_modules/@sap/cds/libx/rest/middleware/read.js +3 -3
  192. package/node_modules/@sap/cds/libx/rest/middleware/upsert.js +2 -2
  193. package/node_modules/@sap/cds/package.json +1 -1
  194. package/node_modules/@sap/cds-compiler/CHANGELOG.md +75 -8
  195. package/node_modules/@sap/cds-compiler/bin/cdsc.js +2 -2
  196. package/node_modules/@sap/cds-compiler/doc/IncompatibleChanges_v7.md +46 -19
  197. package/node_modules/@sap/cds-compiler/lib/api/main.js +10 -7
  198. package/node_modules/@sap/cds-compiler/lib/api/options.js +8 -2
  199. package/node_modules/@sap/cds-compiler/lib/base/csnRefs.js +5 -2
  200. package/node_modules/@sap/cds-compiler/lib/base/message-registry.js +4 -0
  201. package/node_modules/@sap/cds-compiler/lib/base/optionProcessor.js +12 -0
  202. package/node_modules/@sap/cds-compiler/lib/checks/enricher.js +1 -0
  203. package/node_modules/@sap/cds-compiler/lib/compiler/assert-consistency.js +8 -7
  204. package/node_modules/@sap/cds-compiler/lib/compiler/checks.js +3 -3
  205. package/node_modules/@sap/cds-compiler/lib/compiler/define.js +301 -75
  206. package/node_modules/@sap/cds-compiler/lib/compiler/dictionaries.js +2 -0
  207. package/node_modules/@sap/cds-compiler/lib/compiler/extend.js +40 -26
  208. package/node_modules/@sap/cds-compiler/lib/compiler/populate.js +45 -60
  209. package/node_modules/@sap/cds-compiler/lib/compiler/propagator.js +16 -7
  210. package/node_modules/@sap/cds-compiler/lib/compiler/resolve.js +48 -18
  211. package/node_modules/@sap/cds-compiler/lib/compiler/shared.js +7 -6
  212. package/node_modules/@sap/cds-compiler/lib/compiler/tweak-assocs.js +62 -50
  213. package/node_modules/@sap/cds-compiler/lib/compiler/utils.js +29 -14
  214. package/node_modules/@sap/cds-compiler/lib/edm/edmAnnoPreprocessor.js +6 -5
  215. package/node_modules/@sap/cds-compiler/lib/gen/CdlGrammar.checksum +1 -1
  216. package/node_modules/@sap/cds-compiler/lib/gen/CdlParser.js +1119 -1109
  217. package/node_modules/@sap/cds-compiler/lib/gen/Dictionary.json +19 -3
  218. package/node_modules/@sap/cds-compiler/lib/json/from-csn.js +10 -16
  219. package/node_modules/@sap/cds-compiler/lib/json/to-csn.js +58 -39
  220. package/node_modules/@sap/cds-compiler/lib/main.d.ts +8 -0
  221. package/node_modules/@sap/cds-compiler/lib/main.js +1 -0
  222. package/node_modules/@sap/cds-compiler/lib/model/csnUtils.js +4 -0
  223. package/node_modules/@sap/cds-compiler/lib/parsers/AstBuildingParser.js +2 -1
  224. package/node_modules/@sap/cds-compiler/lib/parsers/XprTree.js +8 -0
  225. package/node_modules/@sap/cds-compiler/lib/render/toCdl.js +22 -1
  226. package/node_modules/@sap/cds-compiler/lib/render/toSql.js +17 -2
  227. package/node_modules/@sap/cds-compiler/lib/render/utils/common.js +6 -1
  228. package/node_modules/@sap/cds-compiler/lib/render/utils/operators.js +27 -0
  229. package/node_modules/@sap/cds-compiler/lib/render/utils/standardDatabaseFunctions.js +125 -3
  230. package/node_modules/@sap/cds-compiler/lib/tool-lib/revealInternalProperties.js +2 -1
  231. package/node_modules/@sap/cds-compiler/lib/transform/db/applyTransformations.js +15 -0
  232. package/node_modules/@sap/cds-compiler/lib/transform/db/associations.js +10 -2
  233. package/node_modules/@sap/cds-compiler/lib/transform/db/backlinks.js +22 -6
  234. package/node_modules/@sap/cds-compiler/lib/transform/db/constraints.js +62 -1
  235. package/node_modules/@sap/cds-compiler/lib/transform/db/flattening.js +4 -3
  236. package/node_modules/@sap/cds-compiler/lib/transform/effective/annotations.js +40 -0
  237. package/node_modules/@sap/cds-compiler/lib/transform/effective/flattening.js +17 -1
  238. package/node_modules/@sap/cds-compiler/lib/transform/effective/main.js +20 -0
  239. package/node_modules/@sap/cds-compiler/lib/transform/fioriTreeViews.js +12 -1
  240. package/node_modules/@sap/cds-compiler/lib/transform/forRelationalDB.js +7 -2
  241. package/node_modules/@sap/cds-compiler/lib/transform/odata/adaptAnnotationRefs.js +11 -5
  242. package/node_modules/@sap/cds-compiler/lib/transform/translateAssocsToJoins.js +48 -10
  243. package/node_modules/@sap/cds-compiler/package.json +1 -1
  244. package/node_modules/@sap/cds-mtxs/CHANGELOG.md +49 -0
  245. package/node_modules/@sap/cds-mtxs/bin/cds-mtx-migrate.js +26 -5
  246. package/node_modules/@sap/cds-mtxs/bin/cds-mtx.js +37 -16
  247. package/node_modules/@sap/cds-mtxs/lib/utils.js +23 -7
  248. package/node_modules/@sap/cds-mtxs/package.json +1 -1
  249. package/node_modules/@sap/cds-mtxs/srv/cf/abstract-provisioning-service.js +63 -8
  250. package/node_modules/@sap/cds-mtxs/srv/cf/saas-provisioning-service.js +1 -1
  251. package/node_modules/@sap/cds-mtxs/srv/cf/sms-provisioning-service.js +23 -3
  252. package/node_modules/@sap/cds-mtxs/srv/extensibility/compat/update.js +15 -0
  253. package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/annotations.js +2 -2
  254. package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/config.js +2 -0
  255. package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/index.js +2 -0
  256. package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/protected-namespace.js +45 -0
  257. package/node_modules/@sap/cds-mtxs/srv/extensibility-service.js +30 -16
  258. package/node_modules/@sap/cds-mtxs/srv/jobs-service.js +49 -10
  259. package/node_modules/@sap/cds-mtxs/srv/model-provider.js +28 -4
  260. package/node_modules/@sap/cds-mtxs/srv/plugins/common.js +19 -12
  261. package/node_modules/@sap/cds-mtxs/srv/plugins/hana/ctnr-mgr-base.js +1 -1
  262. package/node_modules/@sap/cds-mtxs/srv/plugins/hana/hdi-ctnr-mgr.js +6 -3
  263. package/node_modules/@sap/cds-mtxs/srv/plugins/hana/serverless.js +271 -0
  264. package/node_modules/@sap/cds-mtxs/srv/plugins/hana.js +7 -10
  265. package/node_modules/@sap/cds-mtxs/srv/worker/job-worker-pool.js +212 -0
  266. package/node_modules/@sap/cds-mtxs/srv/worker/job-worker.js +61 -0
  267. package/node_modules/@sap/xsenv/CHANGELOG.md +7 -0
  268. package/node_modules/@sap/xsenv/package.json +10 -7
  269. package/node_modules/body-parser/node_modules/content-type/README.md +2 -0
  270. package/node_modules/body-parser/node_modules/content-type/dist/index.d.ts +20 -0
  271. package/node_modules/body-parser/node_modules/content-type/dist/index.js +20 -14
  272. package/node_modules/body-parser/node_modules/content-type/dist/index.js.map +1 -1
  273. package/node_modules/body-parser/node_modules/content-type/package.json +1 -1
  274. package/node_modules/hdb/cfg/VERSION +1 -1
  275. package/node_modules/hdb/lib/protocol/ClientInfo.js +16 -3
  276. package/node_modules/hdb/lib/protocol/Connection.js +1 -0
  277. package/node_modules/hdb/package.json +3 -2
  278. package/node_modules/negotiator/lib/accept.js +54 -0
  279. package/node_modules/negotiator/lib/charset.js +10 -34
  280. package/node_modules/negotiator/lib/encoding.js +9 -30
  281. package/node_modules/negotiator/lib/language.js +15 -36
  282. package/node_modules/negotiator/lib/mediaType.js +16 -134
  283. package/node_modules/negotiator/node_modules/content-type/LICENSE +22 -0
  284. package/node_modules/negotiator/node_modules/content-type/README.md +71 -0
  285. package/node_modules/negotiator/node_modules/content-type/dist/index.d.ts +46 -0
  286. package/node_modules/negotiator/node_modules/content-type/dist/index.js +176 -0
  287. package/node_modules/negotiator/node_modules/content-type/dist/index.js.map +1 -0
  288. package/node_modules/negotiator/node_modules/content-type/package.json +52 -0
  289. package/node_modules/negotiator/package.json +16 -10
  290. package/node_modules/qs/.github/THREAT_MODEL.md +3 -3
  291. package/node_modules/qs/CHANGELOG.md +15 -0
  292. package/node_modules/qs/README.md +19 -1
  293. package/node_modules/qs/dist/qs.js +21 -21
  294. package/node_modules/qs/eslint.config.mjs +1 -1
  295. package/node_modules/qs/lib/parse.js +3 -4
  296. package/node_modules/qs/lib/stringify.js +23 -8
  297. package/node_modules/qs/lib/utils.js +10 -3
  298. package/node_modules/qs/package.json +4 -4
  299. package/node_modules/qs/test/parse.js +192 -3
  300. package/node_modules/qs/test/stringify.js +317 -0
  301. package/node_modules/qs/test/utils.js +12 -0
  302. package/node_modules/type-is/node_modules/content-type/README.md +2 -0
  303. package/node_modules/type-is/node_modules/content-type/dist/index.d.ts +20 -0
  304. package/node_modules/type-is/node_modules/content-type/dist/index.js +20 -14
  305. package/node_modules/type-is/node_modules/content-type/dist/index.js.map +1 -1
  306. package/node_modules/type-is/node_modules/content-type/package.json +1 -1
  307. package/node_modules/ws/lib/permessage-deflate.js +3 -1
  308. package/node_modules/ws/package.json +1 -1
  309. package/package.json +2 -2
  310. package/bin/completion/scripts/cds-bash.sh +0 -20
  311. package/bin/completion/scripts/cds-fish.fish +0 -13
  312. package/bin/completion/scripts/cds-ps.ps1 +0 -19
  313. package/bin/completion/scripts/cds-zsh.sh +0 -13
  314. package/lib/deploy/index.js +0 -25
  315. package/lib/import/asyncapi/importAsyncAPI.js +0 -33
  316. package/lib/import/asyncapi/index.js +0 -18
  317. package/lib/import/asyncapi/parserContext.js +0 -454
  318. package/lib/import/asyncapi/utils.js +0 -49
  319. package/node_modules/@sap/cds/libx/_runtime/ucl/queries.js +0 -61
  320. package/node_modules/negotiator/HISTORY.md +0 -114
  321. /package/{lib → bin}/upgrade/context.js +0 -0
  322. /package/{lib → bin}/upgrade/migrations/cds10/migrations.json +0 -0
  323. /package/{lib → bin}/upgrade/preflight/cds-version.js +0 -0
  324. /package/{lib → bin}/upgrade/preflight/project-type.js +0 -0
  325. /package/{lib → bin}/upgrade/steps/analyze/classification.js +0 -0
  326. /package/{lib → bin}/upgrade/steps/analyze/detector.js +0 -0
  327. /package/{lib → bin}/upgrade/steps/analyze/evaluator.js +0 -0
  328. /package/{lib → bin}/upgrade/steps/analyze/reporter.js +0 -0
  329. /package/{lib → bin}/upgrade/steps/analyze/setup.js +0 -0
  330. /package/{lib → bin}/upgrade/steps/analyze/utils/detection.js +0 -0
  331. /package/{lib → bin}/upgrade/steps/analyze/utils/files.js +0 -0
  332. /package/{lib → bin}/upgrade/steps/analyze/utils/grep.js +0 -0
  333. /package/{lib → bin}/upgrade/steps/analyze/utils/yaml.js +0 -0
  334. /package/{lib → bin}/upgrade/util/workspaces.js +0 -0
  335. /package/{lib → bin}/watch/esm-resolve-registration.js +0 -0
  336. /package/{lib → bin}/watch/livereload-server.js +0 -0
  337. /package/{lib → bin}/watch/node-watch.js +0 -0
  338. /package/{lib → bin}/watch/open.js +0 -0
  339. /package/{lib → bin}/watch/watcher.js +0 -0
  340. /package/node_modules/@sap/cds-mtxs/srv/worker/{pool.js → model-worker-pool.js} +0 -0
  341. /package/node_modules/@sap/cds-mtxs/srv/worker/{load.js → model-worker.js} +0 -0
@@ -1,11 +1,24 @@
1
1
  'use strict';
2
2
 
3
+ /**
4
+ * @typedef {object} FunctionRendererContext
5
+ * @property {Function} renderArgs - Renders a function argument node to SQL string.
6
+ * @property {Function} error - Compiler error reporting function.
7
+ * @property {string[]} path - Current CSN path for error reporting.
8
+ * @property {{ embeddingDefaultModel: string, embeddingHanaDefaultRemoteSource: string }} vector - Vector embedding options.
9
+ */
10
+
11
+ /**
12
+ * @typedef {(this: FunctionRendererContext, signature: object) => string} DbFunction
13
+ */
14
+
3
15
  /**
4
16
  * List of functions for which we provide a mapping to the respective SQL dialect.
5
17
  * All functions are lowercase, the caller may treat the function name case-insensitive.
6
18
  *
7
19
  * The `this` context within the functions hold the `renderArgs` function.
8
20
  */
21
+ /** @type {Record<string, Record<string, DbFunction>>} */
9
22
  const oDataFunctions = {
10
23
  // https://www.sqlite.org/lang_corefunc.html
11
24
  sqlite: {
@@ -116,7 +129,7 @@ const oDataFunctions = {
116
129
  // let x = this.renderArgs({ ...signature, args: [ args[0] ] });
117
130
  // const isNegative = x.startsWith("'-"); // Check for leading '-'
118
131
  // x = isNegative ? x.replace('-', '') : x; // remove for easier processing
119
- // const sql = `((cast(substr(${x},2,instr(${x},'DT') - 2) as Integer) + (julianday('-4713-11-25T' || replace(replace(replace(substr(${x},instr(${x},'DT') + 2),'H',':'),'M',':'),'S','Z')) - 0.5)) * 86400)`;
132
+ // const sql = `((cast(substr(${ x },2,instr(${ x },'DT') - 2) as Integer) + (julianday('-4713-11-25T' || replace(replace(replace(substr(${ x },instr(${ x },'DT') + 2),'H',':'),'M',':'),'S','Z')) - 0.5)) * 86400)`;
120
133
  // return isNegative ? `-(${sql})` : sql;
121
134
  // },
122
135
  },
@@ -260,7 +273,7 @@ const oDataFunctions = {
260
273
  },
261
274
  matchespattern(signature) {
262
275
  // case … when only works as column expression (not in where)
263
- // in the where clause, only "${x} LIKE_REGEXPR ${y}" works
276
+ // in the where clause, only "${ x } LIKE_REGEXPR ${ y }" works
264
277
  const args = getArgs(signature);
265
278
  checkArgs.call(this, 'matchespattern', args, 2);
266
279
  const x = this.renderArgs({ ...signature, args: [ args[0] ] });
@@ -556,6 +569,7 @@ const oDataFunctions = {
556
569
  },
557
570
  };
558
571
 
572
+ /** @type {Record<string, Record<string, DbFunction>>} */
559
573
  const hanaFunctions = {
560
574
  sqlite: {
561
575
  /**
@@ -659,6 +673,11 @@ const hanaFunctions = {
659
673
  checkArgs.call(this, 'years_between', args, 2);
660
674
  return `floor((${ hanaFunctions.sqlite.months_between.call(this, signature) }) / 12)`;
661
675
  },
676
+
677
+ //
678
+ // Note: Vector functions for SQLite (cosine_similarity, l2distance, l2normalize and vector_embedding) have the
679
+ // same parameters as on HANA because we provide them via UDFs
680
+ //
662
681
  },
663
682
  postgres: {
664
683
  nano100_between(signature) {
@@ -697,6 +716,33 @@ const hanaFunctions = {
697
716
  checkArgs.call(this, 'years_between', args, 2);
698
717
  return `floor((${ hanaFunctions.postgres.months_between.call(this, signature) }) / 12)::INTEGER`;
699
718
  },
719
+
720
+ //
721
+ // Vector functions for postgres vector support based on the https://github.com/pgvector/pgvector
722
+ //
723
+ cosine_similarity(signature) {
724
+ const args = getArgs(signature);
725
+ checkArgs.call(this, 'cosine_similarity', args, 2);
726
+ const x = this.renderArgs({ ...signature, args: [ args[0] ] });
727
+ const y = this.renderArgs({ ...signature, args: [ args[1] ] });
728
+
729
+ return `1 - cosine_distance(${ x },${ y })`;
730
+ },
731
+ l2distance(signature) {
732
+ const args = getArgs(signature);
733
+ checkArgs.call(this, 'l2distance', args, 2);
734
+ const x = this.renderArgs({ ...signature, args: [ args[0] ] });
735
+ const y = this.renderArgs({ ...signature, args: [ args[1] ] });
736
+
737
+ return `l2_distance(${ x },${ y })`;
738
+ },
739
+ l2normalize(signature) {
740
+ const args = getArgs(signature);
741
+ checkArgs.call(this, 'l2normalize', args, 1);
742
+ const x = this.renderArgs({ ...signature, args: [ args[0] ] });
743
+
744
+ return `l2_normalize(${ x })`;
745
+ },
700
746
  },
701
747
  h2: {
702
748
  nano100_between(signature) {
@@ -757,8 +803,18 @@ const hanaFunctions = {
757
803
  checkArgs.call(this, 'years_between', args, 2);
758
804
  return `floor((${ hanaFunctions.h2.months_between.call(this, signature) }) / 12)`;
759
805
  },
806
+
807
+ //
808
+ // Note: Vector functions for H2 (cosine_similarity, l2distance, l2normalize, and vector_embedding) have the
809
+ // same parameters as on HANA because we provide them via UDFs
810
+ //
811
+ },
812
+ common: {
813
+ vector_embedding(signature) {
814
+ /** @type {FunctionRendererContext} */ const ctx = /** @type {any} */ (this);
815
+ return vectorEmbedding.call(ctx, signature);
816
+ },
760
817
  },
761
- common: {},
762
818
  // identity functions + argument check
763
819
  hana: {
764
820
  nano100_between(signature) {
@@ -797,8 +853,67 @@ const hanaFunctions = {
797
853
  checkArgs.call(this, 'years_between', args, 2);
798
854
  return `years_between(${ this.renderArgs({ ...signature, args }) })`;
799
855
  },
856
+
857
+ //
858
+ // Vector functions - only identity check
859
+ //
860
+ cosine_similarity(signature) {
861
+ const args = getArgs(signature);
862
+ checkArgs.call(this, 'cosine_similarity', args, 2);
863
+ const x = this.renderArgs({ ...signature, args: [ args[0] ] });
864
+ const y = this.renderArgs({ ...signature, args: [ args[1] ] });
865
+
866
+ return `cosine_similarity(${ x },${ y })`;
867
+ },
868
+ l2distance(signature) {
869
+ const args = getArgs(signature);
870
+ checkArgs.call(this, 'l2distance', args, 2);
871
+ const x = this.renderArgs({ ...signature, args: [ args[0] ] });
872
+ const y = this.renderArgs({ ...signature, args: [ args[1] ] });
873
+
874
+ return `l2distance(${ x },${ y })`;
875
+ },
876
+ l2normalize(signature) {
877
+ const args = getArgs(signature);
878
+ checkArgs.call(this, 'l2normalize', args, 1);
879
+ const x = this.renderArgs({ ...signature, args: [ args[0] ] });
880
+
881
+ return `l2normalize(${ x })`;
882
+ },
883
+ vector_embedding(signature) {
884
+ /** @type {FunctionRendererContext} */ const ctx = /** @type {any} */ (this);
885
+ const sql = vectorEmbedding.call(ctx, signature);
886
+ if (sql.match('SAP.'))
887
+ return sql;
888
+ // If the model does not start with SAP an additional fourth parameter
889
+ // is necessary specifying the remote source behind which SAP AI Core lies on HANA
890
+ return `${ sql.substring(0, sql.length - 1) }, ${ this.vector.embeddingHanaDefaultRemoteSource })`;
891
+ },
800
892
  },
801
893
  };
894
+ /**
895
+ * Arguments:
896
+ * 1. (mandatory) property for which to generate a vector
897
+ * 2. (optional) DOCUMENT / QUERY kind for embedding function. If not provided we default to 'DOCUMENT'
898
+ * 3. (optional) model. If not provided we default to a compiler setting or else the SAP NXY model
899
+ * @this {FunctionRendererContext}
900
+ * @param {object} signature
901
+ * @returns {string}
902
+ */
903
+ function vectorEmbedding( signature ) {
904
+ const args = getArgs(signature);
905
+ // Default to kind DOCUMENT if no kind is specified
906
+ if (args.length === 1)
907
+ args.push('DOCUMENT');
908
+ // Default to the compiler option vectorEmbeddingDefaultModel if no model is specified
909
+ if (args.length === 2)
910
+ args.push(this.vector.embeddingDefaultModel);
911
+ checkArgs.call(this, 'vector_embedding', args, 3);
912
+ const field = this.renderArgs({ ...signature, args: [ args[0] ] });
913
+ const kind = this.renderArgs({ ...signature, args: [ args[1] ] });
914
+ const model = this.renderArgs({ ...signature, args: [ args[2] ] });
915
+ return `vector_embedding(${ field }, ${ kind }, ${ model })`;
916
+ }
802
917
 
803
918
  /**
804
919
  * Normalizes `signature.args` to a positional array, handling both
@@ -808,6 +923,13 @@ function getArgs( signature ) {
808
923
  return Array.isArray(signature.args) ? signature.args : Object.values(signature.args);
809
924
  }
810
925
 
926
+ /**
927
+ * @this {FunctionRendererContext}
928
+ * @param {string} funcName
929
+ * @param {any[]} receivedArgs
930
+ * @param {number} expectedLength
931
+ * @param {number | null} alternativeLength
932
+ */
811
933
  function checkArgs( funcName, receivedArgs, expectedLength, alternativeLength = null ) {
812
934
  const expectedMismatch = receivedArgs.length < expectedLength;
813
935
  const alternativeMismatch
@@ -15,6 +15,7 @@
15
15
 
16
16
  const msg = require('../base/messages');
17
17
  const { CompilerAssertion } = require('../base/error');
18
+ const { isLeadingQuery } = require('../compiler/utils');
18
19
 
19
20
  const $inferred = Symbol.for('cds.$inferred');
20
21
  const $location = Symbol.for('cds.$location');
@@ -206,7 +207,7 @@ function revealInternalProperties( model, nameOrPath ) {
206
207
 
207
208
  function elements( dict, parent ) {
208
209
  // do not display elements of leading query as they are the same as the view elements:
209
- return (parent._main && parent._main._leadingQuery === parent)
210
+ return (isLeadingQuery( parent ))
210
211
  ? '{ ... }'
211
212
  : dictionary( dict );
212
213
  }
@@ -41,6 +41,7 @@ function applyTransformationsInternal( parent, prop, customTransformers, artifac
41
41
  mixin: dictionary,
42
42
  ref: pathRef,
43
43
  $origin: () => {}, // no-op
44
+ $backlink: () => undefined,
44
45
  '@': annotation,
45
46
  };
46
47
 
@@ -68,6 +69,8 @@ function applyTransformationsInternal( parent, prop, customTransformers, artifac
68
69
  * @param {object} node The value of node[_prop]
69
70
  */
70
71
  function standard( _parent, _prop, node ) {
72
+ if (_prop === '$backlink') // above line in transformers doesn't seem to help...
73
+ return; // ...in the OData backend
71
74
  if (!node || typeof node !== 'object' ||
72
75
  !{}.propertyIsEnumerable.call( _parent, _prop ) ||
73
76
  (options.skipIgnore && node.$ignore) ||
@@ -420,6 +423,17 @@ function mergeTransformers( transformers, that ) {
420
423
  return remapped;
421
424
  }
422
425
 
426
+ /**
427
+ * Return true if the annotation expression ref node is a simple reference:
428
+ * all ref steps are plain strings, and the node has neither `param` nor `cast`.
429
+ *
430
+ * @param {object} annotation An annotation expression node (has `ref`, optionally `param`, `cast`)
431
+ * @returns {boolean}
432
+ */
433
+ function isSimpleAnnoExprRef(annotation) {
434
+ return annotation.ref && annotation.ref.every(s => typeof s === 'string') && !annotation.param && !annotation.cast;
435
+ }
436
+
423
437
  module.exports = {
424
438
  mergeTransformers,
425
439
  transformExpression,
@@ -427,6 +441,7 @@ module.exports = {
427
441
  applyTransformations,
428
442
  applyTransformationsOnNonDictionary,
429
443
  applyTransformationsOnDictionary,
444
+ isSimpleAnnoExprRef,
430
445
  };
431
446
 
432
447
 
@@ -5,6 +5,7 @@ const {
5
5
  applyTransformationsOnNonDictionary,
6
6
  applyTransformations,
7
7
  implicitAs,
8
+ isSimpleAnnoExprRef,
8
9
  } = require('../../model/csnUtils');
9
10
 
10
11
  /**
@@ -136,7 +137,9 @@ function getFKAccessFinalizer( csn, options, csnUtils, pathDelimiter, processOnI
136
137
  if (obj[anno].ref)
137
138
  transformer.ref(obj[anno], 'ref', obj[anno].ref, path.concat(anno));
138
139
  const annoAfter = JSON.stringify(obj[anno]);
139
- if (annoBefore !== annoAfter && (options.transformation !== 'effective' || obj[anno]['=']))
140
+ if (annoBefore !== annoAfter &&
141
+ (options.transformation !== 'effective' || obj[anno]['=']) &&
142
+ !(obj[anno].ref && isSimpleAnnoExprRef(obj[anno])))
140
143
  obj[anno]['='] = true;
141
144
  });
142
145
  }
@@ -219,7 +222,7 @@ function getFKAccessFinalizer( csn, options, csnUtils, pathDelimiter, processOnI
219
222
  */
220
223
  function getTransformer() {
221
224
  return {
222
- ref: (refOwner, prop, ref, path, grandParent) => {
225
+ ref: (refOwner, prop, ref, path, grandParent, _opt, ctx) => {
223
226
  // [<assoc base>.]<managed assoc>.<field>
224
227
  if (ref.length > 1) {
225
228
  const { links } = inspectRef(path);
@@ -249,6 +252,11 @@ function getFKAccessFinalizer( csn, options, csnUtils, pathDelimiter, processOnI
249
252
  else {
250
253
  refOwner.ref = [ ...ref.slice(0, i), newFkName ];
251
254
  }
255
+ if (ctx?.annoExpr === refOwner) {
256
+ ctx.annoExpr['='] = isSimpleAnnoExprRef(refOwner)
257
+ ? refOwner.ref.join('.')
258
+ : true;
259
+ }
252
260
  }
253
261
  }
254
262
  else {
@@ -175,12 +175,14 @@ function getBacklinkTransformer( csnUtils, messageFunctions, options, pathDelimi
175
175
  * @returns {Array} New on-condition
176
176
  */
177
177
  function transformDollarSelfComparison( assocOp, assoc, assocName, elem, elemName, art, artifactName, path ) {
178
- // Check: The forward link <assocOp> must point back to this artifact
178
+ // Check: The forward link <assocOp> must point back to this artifact.
179
+ // Skip when `$backlink` is present: the core compiler already validated the (possibly
180
+ // redirected/included) target and provided the redirected keys/on
179
181
  // FIXME: Unfortunately, we can currently only check this for non-views (because when a view selects
180
182
  // a backlink association element from an entity, the forward link will point to the entity,
181
183
  // not to the view).
182
184
  // FIXME: This also means that corresponding key fields should be in the select list etc ...
183
- if (!art.query && !art.projection && assoc.target && assoc.target !== artifactName) {
185
+ if (!elem.$backlink && !art.query && !art.projection && assoc.target && assoc.target !== artifactName) {
184
186
  messageFunctions.error( null, path, { id: '$self', name: artifactName, target: assoc.target },
185
187
  'Expected association using $(ID) to point back to $(NAME) but found $(TARGET)' );
186
188
  }
@@ -199,6 +201,16 @@ function getBacklinkTransformer( csnUtils, messageFunctions, options, pathDelimi
199
201
  return [];
200
202
  }
201
203
 
204
+ // Prefer the `$backlink` helper (renaming-aware, target redirected to this artifact)
205
+ // over the backlink's own keys/on, so renamings are considered. Absent for
206
+ // same-entity backlinks, where the plain keys/on below are already correct.
207
+ const backlink = elem.$backlink;
208
+
209
+ if (Array.isArray(backlink))
210
+ return transformDollarSelfComparisonWithUnmanagedAssoc(assocOp, assoc, assocName, elemName, art, path, backlink);
211
+ if (backlink?.keys?.length)
212
+ return transformDollarSelfComparisonWithManagedAssoc(assocOp, assoc, assocName, elemName, art, path, backlink);
213
+
202
214
  if (assoc.keys) {
203
215
  // Transform comparison of $self to managed association into AND-combined foreign key comparisons
204
216
  if (assoc.keys.length > 0)
@@ -230,16 +242,19 @@ function getBacklinkTransformer( csnUtils, messageFunctions, options, pathDelimi
230
242
  * @param {string} elemName
231
243
  * @param {CSN.Artifact} art
232
244
  * @param {CSN.Path} path
245
+ * @param {object} [backlink] renaming-aware `elem.$backlink` (`{ keys }`) to use instead of `assoc.keys`
233
246
  * @returns {Array} New on-condition
234
247
  */
235
- function transformDollarSelfComparisonWithManagedAssoc( assocOp, assoc, originalAssocName, elemName, art, path) {
248
+ function transformDollarSelfComparisonWithManagedAssoc( assocOp, assoc, originalAssocName, elemName, art, path, backlink ) {
236
249
  const conditions = [];
237
250
  // if the element was structured then it was flattened => change of the delimiter from '.' to '_'
238
251
  // this is done in the flattening, but as we do not alter the onCond itself there should be done here as well
239
252
  const assocName = originalAssocName.replace(/\./g, pathDelimiter);
240
253
  elemName = elemName.replace(/\./g, pathDelimiter);
241
254
 
242
- assoc.keys.forEach((k) => {
255
+ const keys = backlink?.keys ?? assoc.keys;
256
+
257
+ keys.forEach((k) => {
243
258
  // Depending on naming conventions, the foreign key may two path steps (hdbcds) or be a single path step with a flattened name (plain, quoted)
244
259
  // With to.hdbcds in conjunction with hdbcds naming, we need to NOT use the alias - else we get deployment errors
245
260
  const keyName = k.as && doA2J ? [ k.as ] : k.ref;
@@ -282,15 +297,16 @@ function getBacklinkTransformer( csnUtils, messageFunctions, options, pathDelimi
282
297
  * @param {string} elemName
283
298
  * @param {CSN.Artifact} art
284
299
  * @param {CSN.Path} path
300
+ * @param {Array} [backlink] renaming-aware `elem.$backlink` ON-condition to use instead of `assoc.on`
285
301
  * @returns {Array} New on-condition
286
302
  */
287
- function transformDollarSelfComparisonWithUnmanagedAssoc( assocOp, assoc, originalAssocName, elemName, art, path ) {
303
+ function transformDollarSelfComparisonWithUnmanagedAssoc( assocOp, assoc, originalAssocName, elemName, art, path, backlink ) {
288
304
  // if the element was structured then it may have been flattened => change of the delimiter from '.' to '_'
289
305
  // this is done in the flattening, but as we do not alter the onCond itself there should be done here as well
290
306
  elemName = elemName.replace(/\./g, pathDelimiter);
291
307
  const assocName = originalAssocName.replace(/\./g, pathDelimiter);
292
308
  // clone the onCond for later use in the path transformation
293
- const newOnCond = cloneCsnNonDict(assoc.on, options);
309
+ const newOnCond = cloneCsnNonDict(backlink ?? assoc.on, options);
294
310
  applyTransformationsOnNonDictionary({ on: newOnCond }, 'on', {
295
311
  ref: (parent, prop, ref) => {
296
312
  let sourceSide = false;
@@ -592,6 +592,67 @@ function createReferentialConstraints( csn, options ) {
592
592
  }
593
593
  }
594
594
 
595
+ /**
596
+ * Add an `ON DELETE CASCADE` referential constraint on the `DraftAdministrativeData_DraftUUID`
597
+ * foreign key of each draft shadow table, so deleting a draft's `DRAFT.DraftAdministrativeData`
598
+ * row removes all its shadow rows.
599
+ *
600
+ * Runs after the draft shadow entities exist (they don't during `createReferentialConstraints`).
601
+ * Their `DraftAdministrativeData` association is unmanaged and points at the service view, so the
602
+ * regular pass skips it; this pass references the `DRAFT.DraftAdministrativeData` table directly.
603
+ *
604
+ * Opt-in via the `draftAdminDataConstraints` option and independent of the global
605
+ * `assertIntegrity` / `assertIntegrityType` switches.
606
+ *
607
+ * @param {CSN.Model} csn
608
+ * @param {CSN.Options} options
609
+ */
610
+ function createDraftAdminDataConstraints( csn, options ) {
611
+ if (options.draftAdminDataConstraints !== true)
612
+ return;
613
+
614
+ const draftAdminData = 'DRAFT.DraftAdministrativeData';
615
+ if (!csn.definitions[draftAdminData])
616
+ return;
617
+
618
+ const delimiter = options.sqlMapping === 'hdbcds' ? '.' : '_';
619
+ const foreignKeyName = `DraftAdministrativeData${ delimiter }DraftUUID`;
620
+
621
+ const validated = !options.integrityNotValidated;
622
+ const enforced = !options.integrityNotEnforced;
623
+
624
+ forEach(csn.definitions, ( artifactName, artifact ) => {
625
+ if (artifact.kind !== 'entity' || artifact.query || artifact.projection)
626
+ return;
627
+ const foreignKey = artifact.elements?.[foreignKeyName];
628
+ const assoc = artifact.elements?.DraftAdministrativeData;
629
+ // only draft shadow tables have both the association and its flattened foreign key
630
+ if (!foreignKey || !assoc || assoc.type !== ASSOCIATION)
631
+ return;
632
+
633
+ const identifierPrefix = options.pre2134ReferentialConstraintNames ? '' : 'c__';
634
+ const identifier = `${ identifierPrefix }${ getResultingName(csn, options.sqlMapping, artifactName) }_DraftAdministrativeData`;
635
+ const mapKey = `${ getResultingName(csn, 'quoted', artifactName) }_DraftAdministrativeData`;
636
+
637
+ if (!('$tableConstraints' in artifact))
638
+ artifact.$tableConstraints = Object.create(null);
639
+ if (!artifact.$tableConstraints.referential)
640
+ artifact.$tableConstraints.referential = Object.create(null);
641
+
642
+ artifact.$tableConstraints.referential[mapKey] = {
643
+ identifier,
644
+ foreignKey: [ foreignKeyName ],
645
+ parentKey: [ 'DraftUUID' ],
646
+ dependentTable: artifactName,
647
+ parentTable: draftAdminData,
648
+ onDelete: 'CASCADE',
649
+ onDeleteRemark: options.testMode ? 'Draft shadow entries are deleted when their DraftAdministrativeData entry is deleted' : null,
650
+ validated,
651
+ enforced,
652
+ };
653
+ });
654
+ }
655
+
595
656
  /**
596
657
  * If the artifact has both, unique- and foreign key constraints, it is possible that the constraints have the same identifier.
597
658
  * This would end in table which can't be activated.
@@ -616,4 +677,4 @@ function assertConstraintIdentifierUniqueness( artifact, artifactName, path, err
616
677
  });
617
678
  }
618
679
 
619
- module.exports = { createReferentialConstraints, assertConstraintIdentifierUniqueness };
680
+ module.exports = { createReferentialConstraints, createDraftAdminDataConstraints, assertConstraintIdentifierUniqueness };
@@ -11,7 +11,7 @@ const { isBuiltinType, isMagicVariable } = require('../../base/builtins');
11
11
  const transformUtils = require('../transformUtils');
12
12
  const { csnRefs } = require('../../base/csnRefs');
13
13
  const { setProp, forEach } = require('../../utils/objectUtils');
14
- const { transformExpression } = require('./applyTransformations');
14
+ const { transformExpression, isSimpleAnnoExprRef } = require('./applyTransformations');
15
15
  const { cloneCsnNonDict } = require('../../base/cloneCsn');
16
16
  const { EdmTypeFacetNames } = require('../../edm/EdmPrimitiveTypeDefinitions');
17
17
  const { adaptAnnotationsRefs } = require('../odata/adaptAnnotationRefs');
@@ -246,7 +246,8 @@ function getStructStepsFlattener( csn, options, messageFunctions, resolved, path
246
246
  adaptRefs.push((...args) => {
247
247
  const refChanged = fn(...args);
248
248
  if (refChanged && annotation['='])
249
- annotation['='] = true;
249
+ // For simple refs (all-string steps, no param/cast), = contains the string representation of the ref.
250
+ annotation['='] = isSimpleAnnoExprRef(annotation) ? annotation.ref.join('.') : true;
250
251
  });
251
252
  }
252
253
  else {
@@ -664,7 +665,7 @@ function handleManagedAssociationsAndCreateForeignKeys( csn, options, messageFun
664
665
  }
665
666
 
666
667
  if (options.transformation === 'effective') {
667
- adaptAnnotationsRefs(fks, csnUtils, messageFunctions, eltPath);
668
+ adaptAnnotationsRefs(fks, csnUtils, messageFunctions, eltPath, options);
668
669
  const validAnnoNames = Object.keys(element).filter(pn => pn[0] === '@' && findAnnotationExpression(element, pn));
669
670
  fks.forEach(fk => copyAnnotations(element, fk[1], false, {}, validAnnoNames));
670
671
  }
@@ -1,6 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  const { CompilerAssertion } = require('../../base/error');
4
+ const { transformAnnotationExpression } = require('../../model/csnUtils');
5
+ const { expressionToCdlString } = require('../../render/toCdl');
4
6
  const { forEach } = require('../../utils/objectUtils');
5
7
 
6
8
  const directMappings = {
@@ -283,6 +285,43 @@ function sealAnnoMagic(csn) {
283
285
  };
284
286
  }
285
287
 
288
+ /**
289
+ * Replace all annotation expression nodes with their CDL-like string representation.
290
+ *
291
+ * @param {CSN.Model} _csn
292
+ * @param {CSN.Options} options
293
+ * @param {object} messageFunctions
294
+ * @returns {object} Transformer object for applyTransformations
295
+ */
296
+ function stringifyAnnotationExpressions( _csn, options, messageFunctions ) {
297
+ // exclude '#' so enum-symbol annotation values are kept as is
298
+ const expressionTransformers = {
299
+ ref: stringifyExpression,
300
+ xpr: stringifyExpression,
301
+ list: stringifyExpression,
302
+ val: stringifyExpression,
303
+ func: stringifyExpression,
304
+ SELECT: stringifyExpression,
305
+ SET: stringifyExpression,
306
+ };
307
+
308
+ return {
309
+ '@': (parent, prop, _anno, path) => transformAnnotationExpression(parent, prop, expressionTransformers, path),
310
+ };
311
+
312
+ function stringifyExpression( expressionNode, _prop, _value, _path, parent, parentProp ) {
313
+ // Keep unchecked refs that already have textual representation.
314
+ if (expressionNode.ref && typeof expressionNode['='] === 'string') {
315
+ delete expressionNode.ref;
316
+ delete expressionNode.param;
317
+ delete expressionNode.cast;
318
+ return;
319
+ }
320
+
321
+ parent[parentProp] = expressionToCdlString(expressionNode, options, messageFunctions);
322
+ }
323
+ }
324
+
286
325
  function isPartOfINAService(csn, artifactName) {
287
326
  const parts = artifactName.split('.');
288
327
  if (parts.length === 1)
@@ -339,4 +378,5 @@ function getOnConditionAsComparisonTuples(on, assocName) {
339
378
  module.exports = {
340
379
  remapODataAnnotations,
341
380
  sealAnnoMagic,
381
+ stringifyAnnotationExpressions,
342
382
  };
@@ -53,6 +53,18 @@ function flattenRefs(csn, options, csnUtils, messageFunctions) {
53
53
  const refFlattener = getStructStepsFlattener(csn, options, messageFunctions, resolved, '_', adaptRefs);
54
54
 
55
55
  forEachDefinition(csn, (def, defName) => {
56
+ // Unbound actions/functions/events: only flatten annotation expressions, not params.
57
+ // Their params may carry $self on-conditions that cannot be resolved without a query context.
58
+ if (def.kind === 'action' || def.kind === 'function' || def.kind === 'event') {
59
+ forEachMemberRecursively(def, (member, memberName, prop, path) => {
60
+ Object.keys(member).filter(pn => pn.startsWith('@') && member[pn]).forEach((pn) => {
61
+ transformAnnotationExpression(member, pn, [ refFlattener ], path);
62
+ adaptRefs.forEach(fn => fn());
63
+ adaptRefs.length = 0;
64
+ });
65
+ }, [ 'definitions', defName ]);
66
+ return;
67
+ }
56
68
  applyTransformationsOnNonDictionary(csn.definitions, defName, refFlattener, { processAnnotations: true, skipDict: { actions: 1 } }, [ 'definitions' ]);
57
69
 
58
70
  adaptRefs.forEach(fn => fn());
@@ -97,8 +109,12 @@ function flattenRefs(csn, options, csnUtils, messageFunctions) {
97
109
  });
98
110
 
99
111
  cleanup.forEach((obj) => {
100
- if (obj.ref && obj.ref[0] === '$self')
112
+ // strip leading $self from ref array and (if it is a string) from '='
113
+ if (obj.ref && obj.ref[0] === '$self') {
101
114
  obj.ref.shift();
115
+ if (typeof obj['='] === 'string' && obj['='].startsWith('$self.'))
116
+ obj['='] = obj['='].slice('$self.'.length);
117
+ }
102
118
  });
103
119
  }
104
120
 
@@ -103,6 +103,25 @@ function effectiveCsn( model, options, messageFunctions ) {
103
103
 
104
104
  resolveTypesInActionsAfterFlattening(csnUtils);
105
105
 
106
+ // Rewrite association keys in unbound action/function params to use flattened names.
107
+ // Not needed for bound actions: their params are reached via the parent entity and handled by flattenFKs in managedToUnmanaged.
108
+ forEachDefinition(csn, (def) => {
109
+ if (def.kind !== 'action' && def.kind !== 'function')
110
+ return;
111
+ if (!def.params)
112
+ return;
113
+ for (const param of Object.values(def.params)) {
114
+ if (!param.elements)
115
+ continue;
116
+ for (const element of Object.values(param.elements)) {
117
+ if (element.keys)
118
+ element.keys.forEach((key) => {
119
+ key.ref = [ key.ref.join('_') ];
120
+ });
121
+ }
122
+ }
123
+ });
124
+
106
125
  processCalculatedElementsInEntities(csn, options);
107
126
  // invalidate csnRef caches after flattening
108
127
  transformerUtils.csnUtils = getUtils(csn, 'init-all');
@@ -113,6 +132,7 @@ function effectiveCsn( model, options, messageFunctions ) {
113
132
  options.remapOdataAnnotations ? annotations.remapODataAnnotations(csn) : {},
114
133
  misc.removeDefinitionsAndProperties(csn, options),
115
134
  options.deriveAnalyticalAnnotations ? annotations.sealAnnoMagic(csn) : {},
135
+ options.stringifyAnnoXpr ? annotations.stringifyAnnotationExpressions(csn, options, messageFunctions) : {},
116
136
  ], null);
117
137
 
118
138
  if (options.addCdsPersistenceName) {
@@ -16,7 +16,7 @@ const { isBuiltinType } = require('../base/builtins');
16
16
  * - the foreign key is of scalar type
17
17
  * Otherwise, appropriate warnings/errors are raised.
18
18
  */
19
- function generateFioriTreeViewAnnotationsAndFields(def, defName, messageFunctions, csnUtils, transformers, options) {
19
+ function generateFioriTreeViewAnnotationsAndFields(def, defName, messageFunctions, csnUtils, transformers, options, csn) {
20
20
  const { error, warning } = messageFunctions;
21
21
  const { isAssociation } = csnUtils;
22
22
  const { setAnnotation, addElement, createScalarElement } = transformers;
@@ -157,6 +157,17 @@ function generateFioriTreeViewAnnotationsAndFields(def, defName, messageFunction
157
157
  }
158
158
 
159
159
  function addHierarchyFields(def, defName) {
160
+ addHierarchyFieldsTo(def, defName);
161
+
162
+ // The localized convenience view is a stand-in for the annotated view at
163
+ // runtime, so it must carry the same hierarchy columns. It is generated
164
+ // before this transform runs, hence it is augmented here explicitly.
165
+ const localizedView = csn?.definitions?.[`localized.${ defName }`];
166
+ if (localizedView)
167
+ addHierarchyFieldsTo(localizedView, `localized.${ defName }`);
168
+ }
169
+
170
+ function addHierarchyFieldsTo(def, defName) {
160
171
  // add elements in elements dictionary
161
172
  const limitedDescendantCount = createScalarElement('LimitedDescendantCount', 'cds.Integer');
162
173
  limitedDescendantCount.LimitedDescendantCount['@Core.Computed'] = true;
@@ -17,7 +17,7 @@ const validate = require('../checks/validator');
17
17
  const { addTenantFields } = require('../transform/addTenantFields');
18
18
  const { addLocalizationViewsWithJoins } = require('../transform/localized');
19
19
  const { timetrace } = require('../utils/timetrace');
20
- const { createReferentialConstraints, assertConstraintIdentifierUniqueness } = require('./db/constraints');
20
+ const { createReferentialConstraints, createDraftAdminDataConstraints, assertConstraintIdentifierUniqueness } = require('./db/constraints');
21
21
  const { setProp, forEach } = require('../utils/objectUtils');
22
22
  const handleExists = require('./db/assocsToQueries/transformExists');
23
23
  const { rewriteCalculatedElementsInViews, processCalculatedElementsInEntities } = require('./db/rewriteCalculatedElements');
@@ -340,6 +340,11 @@ function transformForRelationalDBWithCsn(csn, options, messageFunctions) {
340
340
  // no constraints for drafts
341
341
  generateDrafts(csn, options, pathDelimiter, messageFunctions);
342
342
 
343
+ // the DraftAdministrativeData_DraftUUID foreign key still gets a cascade constraint;
344
+ // must run after generateDrafts, as the shadow tables don't exist before
345
+ if (options.sqlDialect !== 'plain' && options.sqlDialect !== 'h2')
346
+ createDraftAdminDataConstraints(csn, options);
347
+
343
348
  // Set the final constraint paths and produce hana tc indexes if required
344
349
  // See function comment for extensive information.
345
350
  assertUnique.rewrite(csn, options, pathDelimiter);
@@ -362,7 +367,7 @@ function transformForRelationalDBWithCsn(csn, options, messageFunctions) {
362
367
  findAndMarkSqlServiceArtifacts(artifact, artifactName);
363
368
  if (artifact.$dummyService)
364
369
  createServiceDummy(artifact, artifactName, csn, messageFunctions);
365
- generateFioriTreeViews(artifact, artifactName, messageFunctions, csnUtils, { setAnnotation, addElement, createScalarElement }, options);
370
+ generateFioriTreeViews(artifact, artifactName, messageFunctions, csnUtils, { setAnnotation, addElement, createScalarElement }, options, csn);
366
371
  }, transformViews ]);
367
372
 
368
373
  // TODO: Could we maybe merge this with the final applyTransformations?