@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
@@ -4,6 +4,49 @@
4
4
  - The format is based on [Keep a Changelog](https://keepachangelog.com/).
5
5
  - This project adheres to [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## Version 10.1.0 - 2026-09-02
8
+
9
+ ### Added
10
+
11
+ - New `sqlite:memory` preset for `cds.requires.db` runs an in-memory SQLite database, now also in production
12
+ - New `hana-serverless` kind for `cds.requires.db` connects to a HANA Cloud serverless instance (Beta)
13
+ - Node.js-native `fetch` client now resolves named destinations through the SAP BTP Destination service for `NoAuthentication`, `BasicAuthentication`, and `OAuth2ClientCredentials` (proxy type `Internet` only) (beta)
14
+
15
+ ### Changed
16
+
17
+ - `cds.spawn` uses dedicated, short-lived transaction for fetching extended models
18
+ - Messaging webhook endpoints are no longer registered anonymously in production when neither `cds.requires.auth` nor `cds.requires.messaging.xsuaa` is configured.
19
+ - UCL tenant mapping notification handlers will be scheduled as `tenant: receiverTenant` instead of anonymously
20
+
21
+ ### Fixed
22
+
23
+ - `@assert` messages using `{i18n>...}` placeholders are no longer mistaken for structured `error(...)` results
24
+ - JSON `$batch` requests now reject invalid `atomicityGroup` identifiers
25
+ - Scheduling a task via `srv.schedule(...).after(<delay>)` or `.every(<interval>)` with a delay above Node's 32-bit `setTimeout` limit (~24.8 days, e.g. `.after('30d')`) no longer emits a `TimeoutOverflowWarning` or fires almost immediately. Such delays are now armed as chained timers, so the task still fires at its exact scheduled time.
26
+ - OData requests with unknown key names in the key predicate (e.g. `Books(ID=1,sad=2)`) are now rejected with `400 Bad Request` instead of causing a `500` error
27
+ - `cds-rc.js` schema now has a `$id` so `jsonschema` 1.5 resolves internal `$ref`s correctly
28
+ - REST `HEAD` responses now report byte-accurate `Content-Length` headers for Unicode JSON payloads
29
+ - Query properties like `limit` and `recurse` are no longer lost when forwarded to remote services
30
+ - `cds.requires.<name>.service = <name>` (a required service naming itself) no longer fails with a spurious `conflicts with` error on server start
31
+ - `UPDATE` and `DELETE` remote-service-queries, that use `.where` instead of a key to specify their subject, will throw
32
+ - Navigating to or creating under a parent protected by an instance-based `@restrict.where` now returns `404` when the parent is not readable
33
+ - A static `@restrict.where` on a collection-bound action is now enforced, rejecting callers who do not satisfy the condition — previously it was silently ignored
34
+
35
+ ### Removed
36
+
37
+ - UCL GraphQL interface adapter as dead code after UCL deprecated the GraphQL on-boarding flow
38
+
39
+ ## Version 10.0.6 - 2026-08-18
40
+
41
+ ### Fixed
42
+
43
+ - `$apply=filter(...)/groupby(...)/aggregate($count)` with non-UTC `DateTimeOffset` filter values now returns correct results on HANA
44
+ - Generated index page now uses relative hrefs, fixing links when served behind an approuter with a path prefix
45
+ - `$batch` sub-requests returned an empty body and headers when `@opentelemetry/instrumentation-express` (or any instrumentation that wraps Express handlers to arity 2) was active
46
+ - `cds.xt.ModelProviderService` can be served in mtx sidecar
47
+ - Modeled service events were not properly ignored in OData adapter
48
+ - Generic handler for draft-specific actions not correctly being bound to the transaction context
49
+
7
50
  ## Version 10.0.5 - 2026-07-28
8
51
 
9
52
  ### Fixed
@@ -143,6 +186,20 @@
143
186
  - Internal `_initial` phase
144
187
  - Removed support for `async activate()` functions returned from `cds-plugin.js` modules, which was never documented, and deprecated since Oct 2023. If you need to run async code during plugin loading, just return a promise as default export.
145
188
 
189
+ ## Version 9.9.3 - 2026-07-21
190
+
191
+ ### Fixed
192
+
193
+ - Fixed context propagation for local app and remote service calls
194
+
195
+ ## Version 9.9.2 - 2026-06-29
196
+
197
+ ### Fixed
198
+
199
+ - `srv.model` propagation in extensibility scenarios
200
+ - Restored `err.target:'in'` during draft activation with `cds.fiori.draft_messages=false` to avoid the `MULTIPLE_ERRORS` popup
201
+ - `resolveView` prioritizes the original foreign key `parent_ID` if exposed multiple times, e.g., through `*, parent.ID as parentId`
202
+
146
203
  ## Version 9.9.1 - 2026-04-29
147
204
 
148
205
  ### Fixed
@@ -2,7 +2,8 @@ const cds = require('../lib')
2
2
  const { find, path, fs } = cds.utils
3
3
 
4
4
  const odata = endpoint => endpoint.kind.startsWith('odata')
5
- const metadata = endpoint => odata(endpoint) ? `<span>/</span> <a href="${endpoint.path}/$metadata"><span>$metadata</span></a>` : ``
5
+ const rel = path => path.replace(/^\//, '')
6
+ const metadata = endpoint => odata(endpoint) ? `<span>/</span> <a href="${rel(endpoint.path)}/$metadata"><span>$metadata</span></a>` : ``
6
7
  const asHtmlId = s => s.replace(/[.:/$&?@]/g, '_').toLowerCase()
7
8
 
8
9
  module.exports = { get html(){
@@ -22,12 +23,12 @@ module.exports = { get html(){
22
23
  .map (({srv, endpoint}) => `
23
24
  <div id="${asHtmlId(srv.name)}-${endpoint.kind}">
24
25
  <h3 class="header">
25
- <a href="${endpoint.path}"><span>${endpoint.path}</span></a>${metadata(endpoint)} ${_moreLinks(srv, endpoint, undefined, false)}
26
+ <a href="${rel(endpoint.path)}"><span>${endpoint.path}</span></a>${metadata(endpoint)} ${_moreLinks(srv, endpoint, undefined, false)}
26
27
  </h3>
27
28
  <ul>${_entities_in(srv).map (e => `
28
29
  <li id="${asHtmlId(srv.name)}-${endpoint.kind}-${asHtmlId(e)}">
29
30
  <div>
30
- <a href="${endpoint.path}/${e.replace(/\./g, '_')}"><span>${e}</span></a>
31
+ <a href="${rel(endpoint.path)}/${e.replace(/\./g, '_')}"><span>${e}</span></a>
31
32
  </div>
32
33
  ${_moreLinks(srv, endpoint, e)}
33
34
  </li>`).join('')}
@@ -35,7 +36,7 @@ module.exports = { get html(){
35
36
  <ul>${_operations_in(srv).map (e => `
36
37
  <li id="${asHtmlId(srv.name)}-${endpoint.kind}-${asHtmlId(e.name)}" class="operation">
37
38
  <div>
38
- <a href="${endpoint.path}/${e.name}" title="${endpoint.path}/${e.name}"><span>${e.name} ${e.params}</span></a>
39
+ <a href="${rel(endpoint.path)}/${e.name}" title="${endpoint.path}/${e.name}"><span>${e.name} ${e.params}</span></a>
39
40
  </div>
40
41
  </li>`).join('')}
41
42
  </ul>
@@ -80,6 +80,7 @@ export const tests = { name: '@cap/eslint/tests',
80
80
  languageOptions: {
81
81
  globals: {
82
82
  mocha: 'readonly',
83
+ vi: 'readonly',
83
84
  jest: 'readonly',
84
85
  expect: 'readonly',
85
86
  describe: 'writable',
@@ -17,7 +17,7 @@ class Minifier {
17
17
  if (skip_unused === 'services') o.services = 'all'
18
18
  const all = new Map (Object.entries( this.defs ??= csn.definitions || {} ))
19
19
  const children = (n,fn,pre=n+'.') => { for (let [n,d] of all) if (n.startsWith(pre)) fn (n,d) }
20
- const keep = (d,kinds) => d.kind in kinds || _can_minify(d)
20
+ const _keep = (d,kinds) => d.kind in kinds || d['@cds.minify'] === false
21
21
  const _own = o.keep ??= { entity:1, type:1, event:1, action:1, function:1 }
22
22
  const _ext = { event:1, action:1, function:1 }
23
23
  const kept = this.kept = csn.definitions = {}
@@ -31,16 +31,23 @@ class Minifier {
31
31
  }
32
32
  } else {
33
33
  // Otherwise first mark all external services and their children as initially skipped
34
- for (let [s,d] of all) if (d.kind === 'service' && _skip_service(s,d)) {
35
- skipped[s] = 0; children (s, (c,d) => keep(d,_ext) ? this.keep(c,d,s) : skipped[c] = s) // used later on in this.keep()
34
+ for (let [s,d] of all) if (d.kind === 'service' && d['@cds.external'] >= 2) {
35
+ if (d['@cds.minify'] === false) continue
36
+ else skipped[s] = 0
37
+ children (s, (c,d) => _keep(d,_ext) ? this.keep(c,d,s) : skipped[c] = s) // used later on in this.keep()
36
38
  }
37
39
  // Then keep all own services and their children
38
- for (let [s,d] of all) if (d.kind === 'service' && !(s in skipped)) {
39
- this.keep(s,d); children (s, (c,d) => keep(d,_own) ? this.keep(c,d) : skipped[c] = 0)
40
+ for (let [s,d] of all) if (d.kind === 'service') {
41
+ if (s in skipped) continue
42
+ else this.keep(s,d)
43
+ children (s, (c,d) => _keep(d,_own) ? this.keep(c,d) : skipped[c] = 0)
40
44
  }
41
45
  // Also keep remaining non-service entities
42
- for (let [e,d] of all) if (d.kind === 'entity' || !_can_minify(d)) {
43
- e in kept || e in skipped || _skip_entity(e,d) || this.keep(e,d)
46
+ for (let [e,d] of all) if (d.kind === 'entity' || d['@cds.minify'] === false) {
47
+ if (e in skipped || e in kept) continue //> skip already kept or skipped definitions
48
+ if (d['@cds.persistence.skip'] === 'if-unused') continue //> skip initially, they are kept by reference if used
49
+ if (e.endsWith('.texts')) continue //> skip texts entities, they are kept by reference if used
50
+ else this.keep(e,d)
44
51
  }
45
52
  }
46
53
 
@@ -106,7 +113,4 @@ class Minifier {
106
113
 
107
114
  }
108
115
 
109
- const _skip_service = (s,d) => (d['@cds.external'] >= 2) && _can_minify(d)
110
- const _skip_entity = (e,d) => (d['@cds.external'] >= 2 || d['@cds.persistence.skip'] === 'if-unused') && _can_minify(d) || e.endsWith('.texts')
111
- const _can_minify = d => d['@cds.minify'] !== false
112
116
  exports.Minifier = Minifier
@@ -524,7 +524,7 @@ function _merge (dst, src, _profiles) {
524
524
  }
525
525
  else if (v !== undefined) dst[p] = v
526
526
  }
527
- if (profiled.length > 0 && !_profiles.has('production')) {
527
+ if (profiled.length > 1 && !_profiles.has('production')) {
528
528
  const profiles = Array.from(_profiles)
529
529
  profiled.sort((a,b) => profiles.indexOf(b.profile) - profiles.indexOf(a.profile))
530
530
  }
@@ -24,7 +24,8 @@ exports = module.exports = {
24
24
  _resolved() {
25
25
  const requires = { __proto__: this }
26
26
  for (let [name,e] of Object.entries(this)) if (e.service) {
27
- if (!(e.service in requires) || e.override || e.service !== name) requires[e.service] = { ...e, name }
27
+ if (e.service === name) continue
28
+ if (!(e.service in requires) || e.override) requires[e.service] = { ...e, name }
28
29
  else throw new Error (`Config 'cds.requires.${name}.service = ${e.service}' conflicts with 'cds.requires.${e.service}'`)
29
30
  }
30
31
  return requires
@@ -127,9 +128,10 @@ const _db_data = {
127
128
 
128
129
  const _databases = {
129
130
 
130
- "db-defaults": { kind: 'sql', ..._db_data }, //> applied only for cds.requires.db: true
131
-
131
+ "db-defaults": { kind: 'sql', ..._db_data }, //> applied only for cds.requires.db: true
132
+
132
133
  "sql": {
134
+ // REVISIT: should be '[development]': { kind: 'sqlite:memory' },
133
135
  '[development]': { kind: 'sqlite', credentials: { url: ':memory:' } },
134
136
  '[production]': { kind: 'hana' },
135
137
  },
@@ -138,22 +140,33 @@ const _databases = {
138
140
  impl: '@cap-js/sqlite', credentials: { url: 'db.sqlite' },
139
141
  ..._db_data,
140
142
  },
143
+ "sqlite:memory": {
144
+ kind: 'sqlite', credentials: { url: ':memory:' },
145
+ },
141
146
  "hana": {
142
147
  impl: '@cap-js/hana',
143
148
  ..._db_data,
144
149
  },
145
150
  "hana-cloud": {
146
- kind: 'hana', "deploy-format": "hdbtable",
151
+ kind: 'hana',
152
+ "deploy-format": "hdbtable", //> REVISIT: still needed?
153
+ },
154
+ "hana-serverless": {
155
+ kind: 'hana',
156
+ serverless: true,
157
+ vcap: { label: 'hana-cloud', plan: 'serverless' },
158
+ dialect: "hana", //> REVISIT: why needed?
159
+ "deploy-format": "hdbtable", //> REVISIT: still needed?
147
160
  },
161
+
148
162
  "sql-mt": { // For compatibility only
149
163
  '[development]': { kind: 'sqlite' },
150
164
  '[production]': { kind: 'hana-mt' },
151
165
  },
152
166
  "hana-mt": { // For compatibility only
153
- kind: 'hana', "deploy-format": "hdbtable",
154
- "vcap": {
155
- "label": "service-manager"
156
- }
167
+ kind: 'hana',
168
+ "vcap": { "label": "service-manager" },
169
+ "deploy-format": "hdbtable", //> REVISIT: still needed?
157
170
  },
158
171
  }
159
172
 
@@ -277,12 +290,10 @@ const _messaging = {
277
290
  const _platform_services = {
278
291
 
279
292
  ucl: {
280
- model: '@sap/cds/srv/ucl-service.cds',
293
+ model: '@sap/cds/srv/ucl-service.cds'
281
294
  // REVISIT: how to configure such that a cds.connect.to('ucl') returns the already initialized UCLService?
282
295
  // service: 'UCLService',
283
296
  // impl: `${_runtime}/ucl/Service.js`,
284
- // REVISIT: remove default as only needed for push mode
285
- vcap: { label: 'xsuaa' }
286
297
  },
287
298
 
288
299
  destinations: {
@@ -35,11 +35,11 @@ module.exports = exports = {
35
35
  sql_simple_queries: 0,
36
36
  pre_compile_edmxs: false,
37
37
  live_reload: !production,
38
- in_memory_db: !production,
39
38
  test_data: !production,
40
39
  test_mocks: !production,
41
40
  with_mocks: !production,
42
41
  mocked_bindings: !production,
42
+ in_memory_db: true,
43
43
  // skip_unused: 'all',
44
44
  skip_unused: true,
45
45
  deploy_data_onconflict: 'insert',
@@ -223,6 +223,9 @@ module.exports = exports = {
223
223
 
224
224
  remote: {
225
225
  native_fetch: undefined,
226
+ timeout: '10s',
227
+ cache_size: 0,
228
+ cache_expiry_buffer: '5min',
226
229
  },
227
230
 
228
231
  }
@@ -3,6 +3,7 @@ const cds = require('../../index')
3
3
  module.exports = {
4
4
  _version: cds.version,
5
5
 
6
+ $id: 'cdsjsonschema://schemas/cds-rc.json',
6
7
  title: 'JSON schema for CDS configuration',
7
8
  $schema: 'https://json-schema.org/draft-07/schema',
8
9
  description: 'This is a JSON schema representation for CDS project configuration',
@@ -961,12 +962,14 @@ module.exports = {
961
962
  enum: [
962
963
  'hana',
963
964
  'sql',
964
- 'sqlite'
965
+ 'sqlite',
966
+ 'sqlite:memory'
965
967
  ],
966
968
  enumDescriptions: [
967
969
  'SAP HANA',
968
970
  'In-memory SQLite (development), SAP HANA (production)',
969
- 'File-based SQLite'
971
+ 'File-based SQLite',
972
+ 'In-memory SQLite'
970
973
  ]
971
974
  },
972
975
 
@@ -1,6 +1,12 @@
1
1
  const DEBUG = /\b(y|all|plugins)\b/.test(process.env.DEBUG) ? console : undefined // eslint-disable-line no-console
2
2
  const cds = require('.')
3
3
 
4
+ const prioritized = {
5
+ '@sap/cds-mtxs': true, // plugins may register handlers for mtxs services
6
+ '@cap-js/sqlite': true, // to enable override by @cap-js/ai
7
+ '@cap-js/telemetry': true // to allow better instrumentation
8
+ }
9
+
4
10
  /**
5
11
  * Fetch cds-plugins from project's package dependencies.
6
12
  * Called in cds.env to populate the plugins configuration
@@ -8,7 +14,7 @@ const cds = require('.')
8
14
  */
9
15
  exports.fetch = function (DEV = process.env.NODE_ENV !== 'production') {
10
16
  DEBUG?.time ('[cds.plugins] - fetched plugins in')
11
- const plugins = JSON.parse(process.env.CDS_PLUGINS||'{}')
17
+ let plugins = JSON.parse(process.env.CDS_PLUGINS||'{}')
12
18
  fetch_plugins_in (cds.home, false)
13
19
  fetch_plugins_in (cds.root, DEV)
14
20
  function fetch_plugins_in (root, dev) {
@@ -19,6 +25,8 @@ exports.fetch = function (DEV = process.env.NODE_ENV !== 'production') {
19
25
  plugins[each] = { impl }
20
26
  } catch { /* no cds-plugin.js */ }
21
27
  }
28
+ for (const each in prioritized)
29
+ if (each in plugins) plugins = Object.assign({ [each]: plugins[each] }, plugins)
22
30
  DEBUG?.timeEnd ('[cds.plugins] - fetched plugins in')
23
31
  return plugins
24
32
  }
@@ -30,10 +38,6 @@ exports.fetch = function (DEV = process.env.NODE_ENV !== 'production') {
30
38
  exports.activate = async function (plugins = cds.env?.plugins || exports.fetch()) {
31
39
  DEBUG?.time ('[cds.plugins] - loaded plugins in')
32
40
  const all = Object.entries(plugins), { local } = cds.utils
33
- const prioritized = {
34
- '@sap/cds-mtxs': true, // plugins may register handlers for mtxs services
35
- '@cap-js/telemetry': true // to allow better instrumentation
36
- }
37
41
  await Promise.all (all.map (([n,c]) => n in prioritized && _load(n,c)))
38
42
  await Promise.all (all.map (([n,c]) => n in prioritized || _load(n,c)))
39
43
  async function _load (plugin, conf) {
@@ -12,7 +12,7 @@ module.exports = function spawn (o, fn, /** @type {import('../index')} */ cds=th
12
12
  if (cds.model && (cds.env.requires.extensibility || cds.env.requires.toggles)) {
13
13
  const ctx = cds.context
14
14
  const ExtendedModels = require('../srv/srv-models') // the sentinel is automatically started when required
15
- cds.context.model = await ExtendedModels.model4(ctx.tenant, ctx.features)
15
+ cds.context.model = await cds.tx(() => ExtendedModels.model4(ctx.tenant, ctx.features))
16
16
  tx.model = cds.context.model
17
17
  }
18
18
  return Promise.resolve(fn(tx))
@@ -113,5 +113,5 @@ const _ensure_fqn = (x,p,srv, name = x[p]) => {
113
113
 
114
114
  const _unhandled = (srv,req) => {
115
115
  const event = req.event + (req.path ? ' ' + req.path : '')
116
- return req.reject (501, `Service "${srv.name}" has no handler for "${event}".`)
116
+ cds.error (501, `Service "${srv.name}" has no handler for "${event}".`)
117
117
  }
@@ -148,7 +148,7 @@ if (!extensibility) {
148
148
  // helper to get model for tenant/features
149
149
  const _is_extended = extensibility ? ()=> cds.db.exists('cds.xt.Extensions') : ()=> false
150
150
  const _get_model4 = async (tenant, features) => {
151
- const { 'cds.xt.ModelProviderService':mps } = cds.services
151
+ const mps = await cds.connect.to('cds.xt.ModelProviderService')
152
152
  const csn = await mps.getCsn (tenant, features)
153
153
  const nsn = cds.compile.for.nodejs(csn)
154
154
  if (cds.edmxs) await cds.compile.to.edmx.files ( csn,
@@ -389,7 +389,8 @@ exports.sh = function shell (cmd,..._) {
389
389
  */
390
390
  const ms4 = exports.ms4 = (ts, unit, u=unit) => {
391
391
  if (typeof ts === 'string') [,ts,u] = /(\d+) ?(\w*)/.exec(ts) || cds.error `Invalid time span format: ${ts}`
392
- return ts * ms4[u||unit||'ms'] || cds.error `Invalid time span unit: ${unit} in ${ts}`
392
+ const factor = ms4[u||unit||'ms'] || cds.error `Invalid time span unit: ${unit} in ${ts}`
393
+ return ts * factor
393
394
  }
394
395
 
395
396
  /**
@@ -132,9 +132,8 @@ module.exports = cds.service.impl(function () {
132
132
  // If error function was used in @assert expression -> use its output
133
133
  // Note: depending on DB, function result may be JavaScript object or JSON string
134
134
  if (typeof message === 'string') {
135
- if (message[0] === '{')
136
- message = JSON.parse(message) //> it's an error function result
137
- else return error //> it's a plain message string
135
+ if (message[0] !== '{' || message.startsWith('{i18n>')) return error //> it's a plain message string
136
+ message = JSON.parse(message) //> it's an error function result
138
137
  }
139
138
  let { targets = [], ...details } = message
140
139
  if (targets.length) details.target = targets.shift()
@@ -238,7 +238,14 @@ async function enforce_auth(req) {
238
238
  // REVISIT with cds^11
239
239
  // - remove compat_static_auth
240
240
  // - make check on CREATE/ NEW and unbound a compat opt-in
241
- if (cds.env.features.compat_static_auth || req.event in { CREATE: 1, NEW: 1 } || this.operations[req.event]) {
241
+ const boundAction = req.target?.actions?.[req.event]
242
+ if (
243
+ cds.env.features.compat_static_auth ||
244
+ req.event in { CREATE: 1, NEW: 1 } ||
245
+ this.operations[req.event] ||
246
+ // collection-bound actions have no instance to filter -> only a static where can apply
247
+ (boundAction && isBoundToCollection(boundAction))
248
+ ) {
242
249
  const staticAuthRestriction = _getStaticAuthRestrictions(resolvedApplicables)
243
250
  if (staticAuthRestriction.length > 0) {
244
251
  return _handleStaticAuthRestrictions(staticAuthRestriction, req)
@@ -2,6 +2,8 @@ const cds = require('../../cds')
2
2
  const { SELECT } = cds.ql
3
3
 
4
4
  module.exports = exports = cds.service.impl(function () {
5
+ const { parent_skip_auth } = cds.env.features
6
+
5
7
  // prettier-ignore
6
8
  this.on(['CREATE', 'READ', 'UPDATE', 'UPSERT', 'DELETE'], '*', async function handle_crud_requests(req) {
7
9
  if (!cds.db)
@@ -11,18 +13,26 @@ module.exports = exports = cds.service.impl(function () {
11
13
  if (req.target['@cds.persistence.skip'] === true && req.target['@cds.persistence.table'] !== true)
12
14
  return req.reject(501, `Entity "${req.target.name}" is annotated with "@cds.persistence.skip" and cannot be served generically.`)
13
15
 
14
- const { ref } = req.query.INSERT?.into || req.query.SELECT?.from || {}
15
- const check_parent = ref?.length > 1 ? SELECT.one(1).from({ ref: ref.slice(0, -1) }) : null
16
- if (check_parent && req.event === 'CREATE') (await check_parent) || req.reject(404)
17
- else if (req.target?._isSingleton) await handle_singleton_request(req)
18
- else if (req.query?.SELECT && req.locale) req.query.SELECT.localized ??= true
16
+ const { ref } = req.query?.INSERT?.into || req.query?.SELECT?.from || {}
17
+ const parent_exists_query = ref?.length > 1 && !('$parent' in (req.query?.elements ?? {}))
18
+ ? SELECT.one`1 as $parent`.from({ ref: ref.slice(0, -1) })
19
+ : null
20
+ const parent_readable_check = parent_exists_query
21
+ ? async () => (parent_skip_auth ? cds.db : this).run(parent_exists_query).catch(() => null)
22
+ : null
23
+
24
+ if (req.event === 'CREATE' && parent_readable_check != null) (await parent_readable_check()) || req.reject(404)
25
+
26
+ if (req.target?._isSingleton) await handle_singleton_request(req)
27
+
28
+ if (req.query?.SELECT && req.locale) req.query.SELECT.localized ??= true
19
29
 
20
30
  // REVISIT for cds^10: can we always use cds.db.dispatch(req)?
21
31
  const result = req.iterator && !req.objectMode
22
32
  ? await cds.db.dispatch(req)
23
33
  : await cds.run(req.query, req.data)
24
34
 
25
- return await exports._handle_result(req, result, check_parent)
35
+ return await exports._handle_result(req, result, parent_readable_check)
26
36
  })
27
37
  })
28
38
 
@@ -42,14 +52,14 @@ async function handle_singleton_request(req) {
42
52
  req.query.where(singleton)
43
53
  }
44
54
 
45
- async function new_behavior(req, result, parent) {
55
+ async function new_behavior(req, result, parent_readable_check) {
46
56
  const n = result?.affected ?? result?.length ?? result
47
57
 
48
58
  // prettier-ignore
49
59
  switch (req.event) {
50
60
  case 'READ':
51
61
  if (!n && req._etagValidationType === 'if-match') req.reject(412)
52
- if (!n) !parent || (await parent) || req.reject(404)
62
+ if (!n && parent_readable_check != null) (await parent_readable_check()) || req.reject(404)
53
63
  return result
54
64
  case 'INSERT': case 'CREATE':
55
65
  if (result.affected != null) return result //> db service returned [affected]
@@ -453,7 +453,7 @@ const compileUpdatedDraftMessages = (newMessages, persistedMessages, requestData
453
453
  if (!prefixRef) return null
454
454
 
455
455
  const draftMessageTargetPrefix = cds.odata.urlify(
456
- { SELECT: { from: { ref: prefixRef } } },
456
+ { query: { SELECT: { from: { ref: prefixRef } } }, subject: { ref: prefixRef } },
457
457
  { kind: 'odata-v4', model: txModel }
458
458
  ).path
459
459
 
@@ -483,7 +483,7 @@ const compileUpdatedDraftMessages = (newMessages, persistedMessages, requestData
483
483
  }
484
484
 
485
485
  message.prefix = cds.odata.urlify(
486
- { SELECT: { from: { ref: messagePrefixRef } } },
486
+ { query: { SELECT: { from: { ref: messagePrefixRef } } }, subject: { ref: messagePrefixRef } },
487
487
  { kind: 'odata-v4', model: txModel }
488
488
  ).path
489
489
 
@@ -1437,11 +1437,11 @@ const Read = {
1437
1437
 
1438
1438
  // TODO: This seems excessive ... how to compare more efficiently?
1439
1439
  const queryPrefixUrl = cds.odata.urlify(
1440
- { SELECT: { from: { ref: queryPrefixRef } } },
1440
+ { query: { SELECT: { from: { ref: queryPrefixRef } } }, subject: { ref: queryPrefixRef } },
1441
1441
  { kind: 'odata-v4', model: txModel }
1442
1442
  ).path
1443
1443
  const msgPrefixUrl = cds.odata.urlify(
1444
- { SELECT: { from: { ref: msgPrefixRef } } },
1444
+ { query: { SELECT: { from: { ref: msgPrefixRef } } }, subject: { ref: msgPrefixRef } },
1445
1445
  { kind: 'odata-v4', model: txModel }
1446
1446
  ).path
1447
1447
 
@@ -2443,7 +2443,7 @@ async function onCancel(req, next) {
2443
2443
 
2444
2444
  const prefixRef = _extractPrefixRef(req.query.DELETE.from.ref, queryRootEntity)
2445
2445
  const messageTargetPrefix = cds.odata.urlify(
2446
- { SELECT: { from: { ref: prefixRef } } },
2446
+ { query: { SELECT: { from: { ref: prefixRef } } }, subject: { ref: prefixRef } },
2447
2447
  { kind: 'odata-v4', model: req.context.tx.model }
2448
2448
  ).path
2449
2449
 
@@ -2570,6 +2570,7 @@ const _readAfterDraftAction = async function ({ req, payload, action }) {
2570
2570
  }
2571
2571
  }
2572
2572
 
2573
+ // prettier-ignore
2573
2574
  module.exports = cds.service.impl(function () {
2574
2575
  if (!this.entities?.DraftAdministrativeData) return
2575
2576
 
@@ -2577,14 +2578,17 @@ module.exports = cds.service.impl(function () {
2577
2578
  Object.defineProperty(this, '_datasource', { value: cds.db })
2578
2579
 
2579
2580
  // Extend the AppService's API by draft specific functions
2580
- this.new = (draft, key) => ({
2581
- then: (r, e) => this.send('NEW', draft, key).then(r, e),
2582
- for: key => this.send('EDIT', typeof draft === 'string' ? draft.replace(/\.drafts$/, '') : draft.actives, key)
2583
- })
2584
- this.edit = (active, key) => this.send('EDIT', active, key)
2585
- this.save = (draft, key) => this.send('SAVE', draft, key)
2586
- this.cancel = (draft, key) => this.send('CANCEL', draft, key)
2587
- this.discard = (draft, key) => this.send('DISCARD', draft, key)
2581
+ this.new = function (draft, key) {
2582
+ return {
2583
+ then: (r, e) => this.send('NEW', draft, key).then(r, e),
2584
+ for: key => this.send('EDIT', typeof draft === 'string' ? draft.replace(/\.drafts$/, '') : draft.actives, key)
2585
+ }
2586
+ }
2587
+
2588
+ this.edit = function (active, key) { return this.send('EDIT', active, key) }
2589
+ this.save = function (draft, key) { return this.send('SAVE', draft, key) }
2590
+ this.cancel = function (draft, key) { return this.send('CANCEL', draft, key) }
2591
+ this.discard = function (draft, key) { return this.send('DISCARD', draft, key) }
2588
2592
 
2589
2593
  // Override the AppService's handle function
2590
2594
  this.handle = !cds.env.features.legacy_srv_results
@@ -2596,9 +2600,13 @@ module.exports = cds.service.impl(function () {
2596
2600
  return Array.isArray(res) && 'affected' in res ? req.data : res
2597
2601
  }
2598
2602
 
2599
- this.on('NEW', '*', onNew.bind(this))
2600
- this.on('EDIT', '*', onEdit.bind(this))
2601
- this.on('CANCEL', '*', onCancel.bind(this))
2602
- this.on('draftPrepare', '*', onPrepare.bind(this))
2603
+ // NOTE: These handler registrations MUST use inline functions
2604
+ // NOTE: > Arrow functions or functions bound with `.bind` will
2605
+ // NOTE: > ... not be able to access the context tx from `this`
2606
+ this.on('NEW', '*', function (req, next) { return onNew.call(this, req, next) })
2607
+ this.on('EDIT', '*', function (req, next) { return onEdit.call(this, req, next) })
2608
+ this.on('CANCEL', '*', function (req, next) { return onCancel.call(this, req, next) })
2609
+ this.on('draftPrepare', '*', function (req, next) { return onPrepare.call(this, req, next) })
2603
2610
  })
2611
+
2604
2612
  module.exports.compileUpdatedDraftMessages = compileUpdatedDraftMessages
@@ -20,16 +20,18 @@ class EndpointRegistry {
20
20
  this.webhookCallbacks = new Map()
21
21
  this.deployCallbacks = new Map()
22
22
 
23
- const _IS_SECURED = !!(
23
+ const _HAS_APP_AUTH = !!(
24
24
  cds.env.requires.auth &&
25
25
  (cds.env.requires.auth.impl || !(cds.env.requires.auth.kind in { mocked: 1, 'mocked-auth': 1 }))
26
26
  )
27
+ const _HAS_MESSAGING_XSUAA = !!cds.env.requires.messaging?.xsuaa
28
+ const _IS_SECURED = _HAS_APP_AUTH || _HAS_MESSAGING_XSUAA
27
29
  const _IS_PRODUCTION = process.env.NODE_ENV === 'production'
28
30
 
29
31
  cds.app.use(basePath, cds.middlewares.context())
30
32
  if (_IS_SECURED) {
31
33
  // unofficial XSUAA fallback
32
- if (cds.env.requires.messaging?.xsuaa) {
34
+ if (_HAS_MESSAGING_XSUAA) {
33
35
  cds.app.use(basePath, _xsuaa_fallback())
34
36
  } else {
35
37
  cds.app.use(basePath, cds.middlewares.auth())
@@ -38,7 +40,11 @@ class EndpointRegistry {
38
40
  cds.app.use(basePath, (_req, _res, next) => {
39
41
  next(cds.context.user._is_anonymous ? 401 : undefined)
40
42
  })
41
- } else if (_IS_PRODUCTION) LOG.warn('Messaging endpoints not secured')
43
+ } else if (_IS_PRODUCTION) {
44
+ throw new Error(
45
+ 'Messaging endpoints require authentication in production. Configure cds.requires.auth or cds.requires.messaging.xsuaa.'
46
+ )
47
+ }
42
48
 
43
49
  cds.app.use(basePath, express.json({ type: 'application/*+json' }))
44
50
  cds.app.use(basePath, express.json())