@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,5 +1,5 @@
1
1
  {
2
- "version": "10.7.0",
2
+ "version": "10.8.0",
3
3
  "help": "\n# SYNOPSIS\n\n *cds lint* [options] file.js [file.js] [dir]\n\n Runs environment checks and/or checks the specified models\n based on the ESLint framework\n\n# OPTIONS\n \n Basic configuration:\n --no-config-lookup Disable look up for eslint.config.js\n -c, --config path::String Use this configuration instead of eslint.config.js, eslint.config.mjs, or eslint.config.cjs\n --inspect-config Open the config inspector with the current configuration\n --ext [String] Specify additional file extensions to lint\n --global [String] Define global variables\n --parser String Specify the parser to be used\n --parser-options Object Specify parser options\n \n Specify Rules and Plugins:\n --plugin [String] Specify plugins\n --rule Object Specify rules\n \n Fix Problems:\n --fix Automatically fix problems\n --fix-dry-run Automatically fix problems without saving the changes to the file system\n --fix-type Array Specify the types of fixes to apply (directive, problem, suggestion, layout)\n \n Ignore Files:\n --no-ignore Disable use of ignore files and patterns\n --ignore-pattern [String] Patterns of files to ignore\n \n Use stdin:\n --stdin Lint code provided on <STDIN> - default: false\n --stdin-filename String Specify filename to process STDIN as\n \n Handle Warnings:\n --quiet Report errors only - default: false\n --max-warnings Int Number of warnings to trigger nonzero exit code - default: -1\n \n Output:\n -o, --output-file path::String Specify file to write report to\n -f, --format String Use a specific output format - default: stylish\n --color, --no-color Force enabling/disabling of color\n \n Inline configuration comments:\n --no-inline-config Prevent comments from changing config or rules\n --report-unused-disable-directives Adds reported errors for unused eslint-disable and eslint-enable directives\n --report-unused-disable-directives-severity String Chooses severity level for reporting unused eslint-disable and eslint-enable directives - either: off, warn, error, 0, 1, or 2\n --report-unused-inline-configs String Adds reported errors for unused eslint inline config comments - either: off, warn, error, 0, 1, or 2\n \n Caching:\n --cache Only check changed files - default: false\n --cache-file path::String Path to the cache file. Deprecated: use --cache-location - default: .eslintcache\n --cache-location path::String Path to the cache file or directory\n --cache-strategy String Strategy to use for detecting changed files in the cache - either: metadata or content - default: metadata\n \n Suppressing Violations:\n --suppress-all Suppress all violations - default: false\n --suppress-rule [String] Suppress specific rules\n --suppressions-location path::String Specify the location of the suppressions file\n --prune-suppressions Prune unused suppressions - default: false\n --pass-on-unpruned-suppressions Ignore unused suppressions - default: false\n \n Miscellaneous:\n --init Run config initialization wizard - default: false\n --env-info Output execution environment information - default: false\n --no-error-on-unmatched-pattern Prevent errors when pattern is unmatched\n --exit-on-fatal-error Exit with exit code 2 in case of fatal error - default: false\n --no-warn-ignored Suppress warnings when the file list includes ignored files\n --pass-on-no-patterns Exit with exit code 0 in case no file patterns are passed\n --debug Output debugging information\n -h, --help Show help\n -v, --version Output the version number\n --print-config path::String Print the configuration for the given file\n --stats Add statistics to the lint report - default: false\n --flag [String] Enable a feature flag\n --mcp Start the ESLint MCP server\n --concurrency Int|String Number of linting threads, auto to choose automatically, off for no multithreading - default: off\n \n",
4
4
  "options": [
5
5
  "--config",
@@ -1,5 +1,5 @@
1
1
  const cds = require('../cds');
2
- const { SettingsManager } = require('./settings_manager');
2
+ const { SettingsManager, OAUTH_PATH, OAUTH_PATH_LEGACY_TOKEN } = require('./settings_manager');
3
3
  const { ParamCollection } = require('./params');
4
4
  const { getMessage } = require('./util/logging');
5
5
  const { buildResponseError, buildNetworkError, parseResponseBody } = require('./util/request');
@@ -39,28 +39,107 @@ function reqParams(method, params) {
39
39
  const url = params.get('tokenUrl');
40
40
  const d = {};
41
41
  const ignored = {};
42
- if (params.has('subdomain')) {
43
- d.subdomain = params.get('subdomain');
44
- }
45
- if (params.has('refreshToken')) {
46
- d.refresh_token = params.get('refreshToken');
47
- const param = ['passcode', 'clientid'].find(param => params.has(param));
48
- if (param) {
49
- ignored[param] = 'refresh token is present';
42
+ const headers = { 'content-type': 'application/x-www-form-urlencoded' };
43
+ const tls = {};
44
+ if (params.get('directUaa')) {
45
+ d.grant_type = 'client_credentials';
46
+ d.client_id = params.get('clientid');
47
+ if (params.has('key')) {
48
+ tls.cert = params.get('certificate');
49
+ tls.key = params.get('key');
50
+ } else {
51
+ const encoded = Buffer.from(`${params.get('clientid')}:${params.get('clientsecret')}`).toString('base64');
52
+ headers.Authorization = `Basic ${encoded}`;
53
+ }
54
+ } else {
55
+ if (params.has('subdomain')) {
56
+ d.subdomain = params.get('subdomain');
57
+ }
58
+ if (params.has('refreshToken')) {
59
+ d.refresh_token = params.get('refreshToken');
60
+ const param = ['passcode', 'clientid'].find(param => params.has(param));
61
+ if (param) {
62
+ ignored[param] = 'refresh token is present';
63
+ }
64
+ } else if (params.has('passcode')) {
65
+ d.passcode = params.get('passcode');
66
+ } else if (params.has('clientsecret')) {
67
+ d.clientid = params.get('clientid');
68
+ d.clientsecret = params.get('clientsecret');
50
69
  }
51
- } else if (params.has('passcode')) {
52
- d.passcode = params.get('passcode');
53
- } else if (params.has('clientsecret')) {
54
- d.clientid = params.get('clientid');
55
- d.clientsecret = params.get('clientsecret');
56
- } else if (params.has('key')) {
57
- d.clientid = params.get('clientid');
58
- d.key = params.get('key');
59
70
  }
60
71
  const data = new URLSearchParams(d).toString();
61
- return method === 'post'
62
- ? { url, data, ignored }
63
- : { url: `${url}?${data}`, data: undefined, ignored };
72
+ const req = method === 'post'
73
+ ? { url, data, method, headers, ...tls }
74
+ : { url: `${url}?${data}`, data: undefined, method, headers, ...tls };
75
+ return { req, ignored };
76
+ }
77
+
78
+ function toResponse(res, body) {
79
+ const status = res.statusCode;
80
+ return {
81
+ ok: status >= 200 && status < 300,
82
+ status,
83
+ statusText: res.statusMessage ?? '',
84
+ headers: { get: name => res.headers[name.toLowerCase()] },
85
+ json: async () => JSON.parse(body),
86
+ text: async () => body
87
+ };
88
+ }
89
+
90
+ function postTokenViaMtls(url, data, headers, { cert, key }) {
91
+ const https = require('node:https');
92
+ const u = new URL(url);
93
+ return new Promise((resolve, reject) => {
94
+ const request = https.request({
95
+ hostname: u.hostname,
96
+ port: u.port || 443,
97
+ path: `${u.pathname}${u.search}`,
98
+ method: 'POST',
99
+ headers,
100
+ cert,
101
+ key
102
+ }, res => {
103
+ let body = '';
104
+ res.setEncoding('utf8');
105
+ res.on('data', chunk => { body += chunk; });
106
+ res.on('end', () => resolve(toResponse(res, body)));
107
+ });
108
+ request.on('error', reject);
109
+ if (data) {
110
+ request.write(data);
111
+ }
112
+ request.end();
113
+ });
114
+ }
115
+
116
+ async function postTokenTo(req, params) {
117
+ const { url, data, method, headers, cert, key } = req;
118
+ DEBUG?.(`Getting authentication token from ${method.toUpperCase()} ${params.obfuscateQueryParams(url)}`);
119
+ const response = cert
120
+ ? await postTokenViaMtls(url, data, headers, { cert, key })
121
+ : await fetch(url, {
122
+ method: method.toUpperCase(),
123
+ body: data,
124
+ headers
125
+ });
126
+ if (!response.ok) {
127
+ throw await buildResponseError(method, url, response);
128
+ }
129
+ return parseResponseBody(response);
130
+ }
131
+
132
+ async function postToken(req, params) {
133
+ try {
134
+ return await postTokenTo(req, params);
135
+ } catch (e) {
136
+ if (e.status !== 404 || !req.url.includes(OAUTH_PATH)) {
137
+ throw e;
138
+ }
139
+ req.url = req.url.replace(OAUTH_PATH, OAUTH_PATH_LEGACY_TOKEN);
140
+ DEBUG?.(`Token endpoint not found, retrying against legacy path ${params.obfuscateQueryParams(req.url)}`);
141
+ return postTokenTo(req, params);
142
+ }
64
143
  }
65
144
 
66
145
  async function fetchToken(params) {
@@ -71,29 +150,16 @@ async function fetchToken(params) {
71
150
  let responseData, error;
72
151
  const method = 'post';
73
152
  do {
74
- const { url, data, ignored } = reqParams(method, params);
153
+ const { req, ignored } = reqParams(method, params);
75
154
  if (Object.keys(ignored).length) {
76
155
  console.log(`Ignoring parameters for fetching token: ${Object.entries(ignored).map(([param, reason]) => `${param} (${reason})`).join(', ')}.`);
77
156
  }
78
- DEBUG?.(`Getting authentication token from ${method.toUpperCase()} ${params.obfuscateQueryParams(url)}`);
79
157
  error = undefined;
80
158
  try {
81
- const response = await fetch(url, {
82
- method: method.toUpperCase(),
83
- body: data,
84
- headers: { 'content-type': 'application/x-www-form-urlencoded' }
85
- });
86
- if (!response.ok) {
87
- throw await buildResponseError(method, url, response);
88
- }
89
- responseData = await parseResponseBody(response);
159
+ responseData = await postToken(req, params);
90
160
  break;
91
161
  } catch (e) {
92
- if (e.status) {
93
- error = e;
94
- } else {
95
- error = buildNetworkError(method, url, e);
96
- }
162
+ error = e.status ? e : buildNetworkError(method, req.url, e);
97
163
  DEBUG?.(`HTTP status ${error.status}`);
98
164
  if (params.has('refreshToken')) {
99
165
  DEBUG?.('Discarding invalid refresh token');
@@ -122,7 +188,7 @@ async function fetchToken(params) {
122
188
  message += `. Ensure the client credentials are correct`;
123
189
  }
124
190
  } else {
125
- message = 'error on token request';
191
+ message = 'token request failed';
126
192
  }
127
193
  throw new Error(message + '.', { cause: error });
128
194
  }
package/lib/mtx/params.js CHANGED
@@ -178,7 +178,8 @@ class BasicParams {
178
178
  this.password = new Param('password', undefined, { obfuscate: ObfuscationLevel.full });
179
179
  this.clientid = new Param('clientid', undefined);
180
180
  this.clientsecret = new Param('clientsecret', undefined, { obfuscate: ObfuscationLevel.partial });
181
- this.key = new Param('key', undefined, { obfuscate: ObfuscationLevel.partial }); // private key of client certificate
181
+ this.certificate = new Param('certificate', undefined, { obfuscate: ObfuscationLevel.partial }); // client certificate for mTLS
182
+ this.key = new Param('key', undefined, { obfuscate: ObfuscationLevel.partial }); // private key of the client certificate
182
183
  this.tokenStorage = new Param('tokenStorage', undefined, { allowedValues: ['plain', 'keyring'] });
183
184
  this.clearOtherTokenStorage = new Param('clearOtherTokenStorage', false, { internal: true });
184
185
  this.plain = new Param('plain', false, { internal: true }); // for backward compatibility - superseded by tokenStorage
@@ -195,7 +196,6 @@ class BasicParams {
195
196
  }
196
197
  }
197
198
 
198
- // TODO pass these as extra arguments to lib functions
199
199
  /**
200
200
  * All known params including those needed for specific commands.
201
201
  */
@@ -216,6 +216,7 @@ class AllParams extends BasicParams {
216
216
 
217
217
  // `login` PARAMS
218
218
  this.skipToken = new Param('skipToken', false, { internal: true });
219
+ this.directUaa = new Param('directUaa', false, { internal: true }); // client-credentials login goes directly to the authorization server
219
220
  this.saveRefreshToken = new Param('saveRefreshToken', false, { internal: true });
220
221
 
221
222
  // `logout` PARAMS
@@ -34,9 +34,10 @@ const KEYRING_DESC = {
34
34
  };
35
35
 
36
36
  const MTX_FULLY_QUALIFIED = 'com.sap.cds.mtx';
37
- const OAUTH_PATH_LEGACY = '/mtx/v1/oauth/token';
38
- const OAUTH_PATH = '/-/cds/login/token';
39
- const OAUTH_META_PATH = '/-/cds/login/authorization-metadata';
37
+ const OAUTH_PATH_LEGACY_TOKEN = '/-/cds/login/token';
38
+ const OAUTH_PATH = '/-/cds/login/grant';
39
+ const OAUTH_META_PATH = '/-/cds/login/grant-metadata';
40
+ const OAUTH_UAA_PATH = '/oauth/token';
40
41
 
41
42
  const SETTINGS_DIR = path.join(os.homedir(), CONFIG_SUBDIRS[os.platform()] || '', MTX_FULLY_QUALIFIED);
42
43
  const SETTINGS_FILE = 'projects.json';
@@ -102,12 +103,40 @@ async function getTokenUrl(params, renewUrl) {
102
103
  if (!params.has('appUrl')) {
103
104
  throw 'Failed to determine token URL: app URL not given';
104
105
  }
106
+ if (params.has('clientid')) {
107
+ return deriveUaaTokenUrl(params);
108
+ }
105
109
  return appUrlWith(OAUTH_PATH, params);
106
110
  }
107
111
 
108
- async function fetchPasscodeUrl(params) {
112
+ function uaaTokenUrl(passcodeUrl, { mtls } = {}) {
113
+ const url = new URL(passcodeUrl);
114
+ url.pathname = url.pathname.replace(/\/passcode\/*$/, '').replace(/\/+$/, '') + OAUTH_UAA_PATH;
115
+ url.search = '';
116
+ if (mtls) {
117
+ url.hostname = url.hostname.replace(/\.authentication\./, '.authentication.cert.');
118
+ }
119
+ return url.toString();
120
+ }
121
+
122
+ async function deriveUaaTokenUrl(params) {
123
+ const mtls = params.has('key');
124
+ const metadata = await fetchAuthMetadata(params);
125
+ const announced = mtls ? metadata?.cert_token_url : metadata?.token_url;
126
+ const passcodeUrl = metadata?.passcode_url;
127
+ const tokenUrl = announced ?? (passcodeUrl && uaaTokenUrl(passcodeUrl, { mtls }));
128
+ if (!tokenUrl) {
129
+ throw 'Cannot determine the authorization server for client-credentials login. ' +
130
+ 'Ensure MTX is running with extensibility enabled and up to date.';
131
+ }
132
+ params.set('directUaa', true);
133
+ DEBUG?.(`Derived authorization-server token URL for ${mtls ? 'mTLS' : 'client-credentials'} login: ${tokenUrl}`);
134
+ return tokenUrl;
135
+ }
136
+
137
+ async function fetchAuthMetadata(params) {
109
138
  let fetchUrl = appUrlWith(OAUTH_META_PATH, params);
110
- DEBUG?.(`Trying to get passcode URL from GET`, fetchUrl);
139
+ DEBUG?.(`Trying to get authorization metadata from GET`, fetchUrl);
111
140
  if (params.has('subdomain')) {
112
141
  const u = new URL(fetchUrl);
113
142
  u.searchParams.set('subdomain', params.get('subdomain'));
@@ -124,10 +153,10 @@ async function fetchPasscodeUrl(params) {
124
153
  if (error.status === 404) {
125
154
  DEBUG?.(`Request unsupported by server, ignoring (${error.message.replace(/ *Details:.*/s, '')})`);
126
155
  } else if (error.status) {
127
- DEBUG?.(getMessage(`Getting passcode URL failed`, { error }));
156
+ DEBUG?.(getMessage(`Getting authorization metadata failed`, { error }));
128
157
  } else {
129
158
  const netError = buildNetworkError('GET', fetchUrl, error);
130
- DEBUG?.(getMessage(`Getting passcode URL failed`, { error: netError }));
159
+ DEBUG?.(getMessage(`Getting authorization metadata failed`, { error: netError }));
131
160
  }
132
161
  return undefined;
133
162
  }
@@ -139,7 +168,7 @@ async function fetchPasscodeUrl(params) {
139
168
  DEBUG?.(`Unsupported signed metadata received. Since these should take precedence, ignoring response.`);
140
169
  return undefined;
141
170
  }
142
- return responseData.passcode_url;
171
+ return responseData;
143
172
  }
144
173
 
145
174
  function getKeyringAccountName(params) {
@@ -289,8 +318,9 @@ class SettingsManager {
289
318
  }
290
319
  async function updateTokenUrl() {
291
320
  const tokenUrl = secure(params.get('tokenUrl'), 'token URL');
321
+ const machineLogin = params.has('clientid');
292
322
  const renewUrl = !logout && !params.get('skipToken')
293
- && (!tokenUrl || tokenUrl.includes('//-/cds') || tokenUrl.includes(OAUTH_PATH_LEGACY)
323
+ && (machineLogin || !tokenUrl || tokenUrl.includes('//-/cds') || !tokenUrl.includes(OAUTH_PATH)
294
324
  || params.get('appUrl') !== loadedSettings.get('appUrl')
295
325
  || params.get('subdomain') !== loadedSettings.get('subdomain'));
296
326
  if (renewUrl) {
@@ -303,7 +333,6 @@ class SettingsManager {
303
333
  }
304
334
  }
305
335
  }
306
-
307
336
  await updateAppUrl();
308
337
  await updateTokenUrl();
309
338
  }
@@ -353,16 +382,9 @@ class SettingsManager {
353
382
  throw 'Clientsecret cannot be empty';
354
383
  }
355
384
  }
356
- async function addKey() {
357
- params.set('key', await Question.askQuestion('key: ', undefined, true));
358
- console.log();
359
- if (params.get('key') === '') {
360
- throw 'Key cannot be empty';
361
- }
362
- }
363
385
  async function addPasscode() {
364
386
  if (!params.has('passcodeUrl')) {
365
- const passcodeUrl = await fetchPasscodeUrl(params);
387
+ const passcodeUrl = (await fetchAuthMetadata(params))?.passcode_url;
366
388
  if (passcodeUrl) {
367
389
  params.set('passcodeUrl', passcodeUrl);
368
390
  }
@@ -440,15 +462,8 @@ class SettingsManager {
440
462
  return;
441
463
  }
442
464
 
443
- if (params.get('clientid') && !logout) {
444
- if (params.has('key')) {
445
- if (params.get('key') === 'ask') {
446
- params.delete('key');
447
- await addKey();
448
- }
449
- } else if (!params.has('clientsecret')) {
450
- await addClientSecret();
451
- }
465
+ if (params.get('clientid') && !logout && !params.has('clientsecret') && !params.has('key')) {
466
+ await addClientSecret();
452
467
  }
453
468
 
454
469
  await addAuthSettings();
@@ -714,5 +729,7 @@ class SettingsManager {
714
729
  module.exports = {
715
730
  SettingsManager,
716
731
  other,
717
- notifyLogin
732
+ notifyLogin,
733
+ OAUTH_PATH,
734
+ OAUTH_PATH_LEGACY_TOKEN
718
735
  };
@@ -20,7 +20,6 @@ const DEFAULT_LOCALHOST_PASSWORD = '';
20
20
 
21
21
  module.exports = class TenantAction {
22
22
 
23
- // TODO JSDoc
24
23
  /**
25
24
  * @param command {string} the command to execute: 'subscribe', 'upgrade' or 'unsubscribe'
26
25
  */
@@ -0,0 +1,62 @@
1
+ const CLIENT_ID_ENV = 'CDS_LOGIN_CLIENT_ID';
2
+ const CLIENT_SECRET_ENV = 'CDS_LOGIN_CLIENT_SECRET';
3
+ const CLIENT_CERT_ENV = 'CDS_LOGIN_CLIENT_CERT';
4
+ const CLIENT_KEY_ENV = 'CDS_LOGIN_CLIENT_KEY';
5
+
6
+ function clientId(inlineId) {
7
+ const clientid = inlineId ?? process.env[CLIENT_ID_ENV];
8
+ if (!clientid) {
9
+ throw `Client ID required: pass it as --client <id> or via the ${CLIENT_ID_ENV} environment variable.`;
10
+ }
11
+ return clientid;
12
+ }
13
+
14
+ function splitFirst(value, separator) {
15
+ const i = value.indexOf(separator);
16
+ return i === -1 ? [value, undefined] : [value.slice(0, i), value.slice(i + separator.length)];
17
+ }
18
+
19
+ /**
20
+ * Resolve `--client` credentials, each part falling back to the environment
21
+ * (`CDS_LOGIN_CLIENT_ID`/`CDS_LOGIN_CLIENT_SECRET`). Splits on the first colon only;
22
+ * an empty client ID (`:secret`) is rejected.
23
+ * @returns {{ clientid?: string, clientsecret?: string }}
24
+ */
25
+ function clientCredentials(clientOption) {
26
+ if (!clientOption) {
27
+ return {};
28
+ }
29
+ const [id, secret] = typeof clientOption === 'string' ? splitFirst(clientOption, ':') : [];
30
+ return { clientid: clientId(id), clientsecret: secret ?? process.env[CLIENT_SECRET_ENV] };
31
+ }
32
+
33
+ /**
34
+ * Resolve `--mtls` credentials: client ID inline or from `CDS_LOGIN_CLIENT_ID`,
35
+ * certificate and key only from `CDS_LOGIN_CLIENT_CERT`/`CDS_LOGIN_CLIENT_KEY`.
36
+ * An inline `:key` is rejected.
37
+ * @returns {{ clientid?: string, certificate?: string, key?: string }}
38
+ */
39
+ function clientCertificate(mtlsOption) {
40
+ if (!mtlsOption) {
41
+ return {};
42
+ }
43
+ if (typeof mtlsOption === 'string' && mtlsOption.includes(':')) {
44
+ throw `The client key cannot be passed on the command line. Pass only the client ID as --mtls <id>, and provide the certificate and key via the ${CLIENT_CERT_ENV} and ${CLIENT_KEY_ENV} environment variables.`;
45
+ }
46
+ const id = typeof mtlsOption === 'string' ? mtlsOption : undefined;
47
+ const certificate = process.env[CLIENT_CERT_ENV];
48
+ const key = process.env[CLIENT_KEY_ENV];
49
+ if (!certificate || !key) {
50
+ throw `Client certificate and key required: set the ${CLIENT_CERT_ENV} and ${CLIENT_KEY_ENV} environment variables.`;
51
+ }
52
+ return { clientid: clientId(id), certificate, key };
53
+ }
54
+
55
+ module.exports = {
56
+ clientCredentials,
57
+ clientCertificate,
58
+ CLIENT_ID_ENV,
59
+ CLIENT_SECRET_ENV,
60
+ CLIENT_CERT_ENV,
61
+ CLIENT_KEY_ENV
62
+ };
@@ -4,6 +4,23 @@
4
4
  - The format is based on [Keep a Changelog](http://keepachangelog.com/).
5
5
  - This project adheres to [Semantic Versioning](http://semver.org/).
6
6
 
7
+ ## [3.1.0](https://github.com/cap-js/cds-dbs/compare/db-service-v3.0.1...db-service-v3.1.0) (2026-09-07)
8
+
9
+
10
+ ### Added
11
+
12
+ * rank $search results by relevance ([#1725](https://github.com/cap-js/cds-dbs/issues/1725)) ([bc93160](https://github.com/cap-js/cds-dbs/commit/bc931601a721f7c9e00b89e6844ba064352b541d))
13
+
14
+
15
+ ### Fixed
16
+
17
+ * **cqn4sql:** reject overly nested query expressions instead of crashing ([#1712](https://github.com/cap-js/cds-dbs/issues/1712)) ([29a45b7](https://github.com/cap-js/cds-dbs/commit/29a45b7daadbc77433b882148700d73c00efae62))
18
+ * don't throw when releasing/destroying a resource that's no longer in the pool ([#1696](https://github.com/cap-js/cds-dbs/issues/1696)) ([5d3b277](https://github.com/cap-js/cds-dbs/commit/5d3b277a1cf7cac02e41f2f24975a8e9473e5b5e))
19
+ * exclude cds.Vector from wildcard select expansion ([#1716](https://github.com/cap-js/cds-dbs/issues/1716)) ([398bacc](https://github.com/cap-js/cds-dbs/commit/398bacc2a74883dcd93acba288deae362570a4c1))
20
+ * INSERT.from(SELECT) used non-existent `value` ([#1565](https://github.com/cap-js/cds-dbs/issues/1565)) ([fd98844](https://github.com/cap-js/cds-dbs/commit/fd98844c83a78d6cf2b0b71344d3ee1d88528106))
21
+ * **pool:** recover lost connection after stale acquire timeout ([#1724](https://github.com/cap-js/cds-dbs/issues/1724)) ([cf6af99](https://github.com/cap-js/cds-dbs/commit/cf6af991d02be7cf5f861e2a424d4d733b8f9238))
22
+ * pql groupby path expression ([#1700](https://github.com/cap-js/cds-dbs/issues/1700)) ([82b5e03](https://github.com/cap-js/cds-dbs/commit/82b5e0385e680321f30c352f0f78ade6d25259a6))
23
+
7
24
  ## [3.0.1](https://github.com/cap-js/cds-dbs/compare/db-service-v3.0.0...db-service-v3.0.1) (2026-06-29)
8
25
 
9
26
 
@@ -150,7 +150,7 @@ constructor (factory, options = {}) {
150
150
  return
151
151
  }
152
152
  const loan = this._loans.get(resource)
153
- if (!loan) throw new Error('Resource not currently part of this pool')
153
+ if (!loan) return
154
154
  this._loans.delete(resource)
155
155
  const pooledResource = loan.pooledResource
156
156
  pooledResource.idle()
@@ -164,7 +164,7 @@ constructor (factory, options = {}) {
164
164
  return
165
165
  }
166
166
  const loan = this._loans.get(resource)
167
- if (!loan) throw new Error('Resource not currently part of this pool')
167
+ if (!loan) return
168
168
  this._loans.delete(resource)
169
169
  const pooledResource = loan.pooledResource
170
170
  await this.#destroy(pooledResource)
@@ -212,16 +212,13 @@ constructor (factory, options = {}) {
212
212
  for (let i = 0; i < needed; i++) this.#createResource()
213
213
  }
214
214
  const dispense = async resource => {
215
- const request = this._queue.shift()
215
+ let request = this._queue.shift()
216
+ while (request && request.state !== RequestState.PENDING) request = this._queue.shift()
216
217
  if (!request) {
217
218
  resource.idle()
218
219
  this._available.add(resource)
219
220
  return false
220
221
  }
221
- if (request.state !== RequestState.PENDING) {
222
- this.#dispense()
223
- return false
224
- }
225
222
  this._loans.set(resource.obj, { pooledResource: resource })
226
223
  resource.update(ResourceState.ALLOCATED)
227
224
  request.resolve(resource.obj)
@@ -18,7 +18,7 @@ class CQN2PQLRenderer extends CQN2SQL {
18
18
 
19
19
  column_expr(x, q) {
20
20
  // omit alias when target is a single source
21
- if (q.SELECT.from.ref && x?.ref) x.ref = x.ref.slice(-1)
21
+ if (q.SELECT.from?.ref && x?.ref) x.ref = x.ref.slice(-1)
22
22
  return super.column_expr(x, q)
23
23
  }
24
24
 
@@ -1088,7 +1088,7 @@ class CQN2SQLRenderer {
1088
1088
 
1089
1089
  const extractions = this._managed = this.managed(columns.map(c => ({ name: c, sql: `NEW.${this.quote(c)}` })), elements)
1090
1090
  const sql = extractions.length > columns.length
1091
- ? `SELECT ${extractions.map(c => `${c.insert} AS ${this.quote(c.name)}`)} FROM (${this.SELECT(src)}) AS NEW`
1091
+ ? `SELECT ${extractions.map((c, i) => `${i < columns.length ? c.insert : c.onInsert} AS ${this.quote(c.name)}`)} FROM (${this.SELECT(src)}) AS NEW`
1092
1092
  : this.SELECT(src)
1093
1093
  if (extractions.length > columns.length) columns = this.columns = extractions.map(c => c.name)
1094
1094
  this.sql = `INSERT INTO ${this.quote(entity)}${alias ? ' as ' + this.quote(alias) : ''} (${columns.map(c => this.quote(transitions.mapping.get(c)?.ref?.[0] || c))}) ${sql}`
@@ -1161,12 +1161,12 @@ class CQN2SQLRenderer {
1161
1161
  const extractions = this._managed
1162
1162
  if (this.values) this.values = [] // Clear previously computed values
1163
1163
  const src = this.cqn4sql(UPSERT.from || UPSERT.as)
1164
- const aliasedQuery = cds.ql.SELECT
1165
- .columns(src.SELECT.columns
1166
- .map((c, i) => ({ ref: [this.column_name(c)], as: this.columns[i] }))
1167
- )
1168
- .from(src)
1169
- sql = `SELECT ${extractions.map(c => `${c.upsert}`)} FROM (${this.SELECT(aliasedQuery)}) AS NEW LEFT JOIN ${this.quote(entity)} AS OLD ON ${keyCompare}`
1164
+ const aliasedQuery = `SELECT ${[
1165
+ ...src.SELECT.columns.map((c, i) => this.column_expr({ ref: [this.column_name(c)], as: this.columns[i] })),
1166
+ ...extractions.slice(src.SELECT.columns.length).map(c => `${elements[c.name].key ? c.onInsert : 'NULL'} AS ${this.quote(c.name)}`), // fill in missing default values
1167
+ ]} FROM (${this.SELECT(src)})`
1168
+
1169
+ sql = `SELECT ${extractions.map(c => elements[c.name].key ? `NEW.${this.quote(c.name)}` : c.upsert)} FROM(${aliasedQuery}) AS NEW LEFT JOIN ${this.quote(entity)} AS OLD ON ${keyCompare} `
1170
1170
  if (extractions.length > columns.length) columns = this.columns = extractions.map(c => c.name)
1171
1171
  this.entries = [this.values]
1172
1172
  }
@@ -1574,9 +1574,11 @@ class CQN2SQLRenderer {
1574
1574
 
1575
1575
  managed_extract(name, element, converter) {
1576
1576
  const { UPSERT, INSERT } = this.cqn
1577
- const extract = !(INSERT?.entries || UPSERT?.entries) && (INSERT?.rows || UPSERT?.rows)
1578
- ? `value->>${this.string(`$[${this.columns.indexOf(name)}]`)}`
1579
- : `value->>${this.string(`$.${JSON.stringify(name)}`)}`
1577
+ const extract = (INSERT?.entries || UPSERT?.entries)
1578
+ ? `value->>${this.string(`$.${JSON.stringify(name)}`)}`
1579
+ : (INSERT?.rows || UPSERT?.rows)
1580
+ ? `value->>${this.string(`$[${this.columns.indexOf(name)}]`)}`
1581
+ : `NEW.${this.quote(name)}` // in case of (INSERT?.from || UPSERT?.from)
1580
1582
  const sql = converter?.(extract) || extract
1581
1583
  return { extract, sql }
1582
1584
  }
@@ -1587,7 +1589,9 @@ class CQN2SQLRenderer {
1587
1589
  }
1588
1590
 
1589
1591
  managed_default(name, managed, src) {
1590
- return `(CASE WHEN json_type(value,${this.managed_extract(name).extract.slice(8)}) IS NULL THEN ${managed} ELSE ${src} END)`
1592
+ const { UPSERT, INSERT } = this.cqn
1593
+ const isJson = INSERT?.entries || UPSERT?.entries || INSERT?.rows || UPSERT?.rows
1594
+ return `(CASE WHEN ${isJson ? `json_type(value,${this.managed_extract(name).extract.slice(8)})` : `NEW.${this.quote(name)}`} IS NULL THEN ${managed} ELSE ${src} END)`
1591
1595
  }
1592
1596
  }
1593
1597