@sap/cds-dk 10.0.6 → 10.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (326) hide show
  1. package/CHANGELOG.md +107 -0
  2. package/bin/add.js +7 -23
  3. package/bin/bind.js +10 -0
  4. package/bin/build.js +20 -34
  5. package/bin/cds.js +1 -1
  6. package/bin/compile/index.js +15 -41
  7. package/bin/completion/completionFs.js +11 -8
  8. package/bin/completion/index.js +592 -80
  9. package/bin/completion/scripts/cds.fish +568 -0
  10. package/bin/completion/scripts/cds.ps1 +329 -0
  11. package/bin/completion/scripts/cds.sh +261 -0
  12. package/bin/completion/scripts/cds.zsh +230 -0
  13. package/bin/completion/templates/cds-tmpl.fish +65 -0
  14. package/bin/completion/templates/cds-tmpl.ps1 +208 -0
  15. package/bin/completion/templates/cds-tmpl.sh +93 -0
  16. package/bin/completion/templates/cds-tmpl.zsh +74 -0
  17. package/bin/deploy/index.js +7 -1
  18. package/bin/deploy/options.js +25 -0
  19. package/{lib → bin}/deploy/to-hana/hana.js +8 -8
  20. package/{lib → bin}/deploy/to-hana/hdiDeployUtil.js +1 -1
  21. package/bin/deploy/{to-hana.js → to-hana/index.js} +1 -1
  22. package/{lib → bin}/deploy/to-hana/mtaUtil.js +1 -1
  23. package/bin/deploy/to-sql.js +0 -2
  24. package/bin/export.js +35 -5
  25. package/bin/help/export.md +3 -0
  26. package/bin/help.js +1 -5
  27. package/bin/import.js +6 -0
  28. package/bin/init.js +5 -24
  29. package/bin/inspect.js +6 -0
  30. package/bin/login.js +26 -20
  31. package/bin/pull.js +19 -6
  32. package/bin/push.js +19 -6
  33. package/bin/up.js +14 -11
  34. package/{lib → bin}/upgrade/constants.js +1 -1
  35. package/bin/{upgrade.js → upgrade/index.js} +2 -2
  36. package/{lib → bin}/upgrade/preflight/consistency.js +1 -1
  37. package/{lib → bin}/upgrade/preflight/index.js +1 -1
  38. package/{lib → bin}/upgrade/steps/analyze/index.js +1 -1
  39. package/{lib → bin}/upgrade/steps/install.js +1 -1
  40. package/{lib → bin}/upgrade/steps/openrewrite.js +1 -1
  41. package/{lib → bin}/upgrade/steps/removals.js +1 -1
  42. package/{lib → bin}/upgrade/steps/rewrite.js +1 -1
  43. package/{lib → bin}/upgrade/steps/verify.js +1 -1
  44. package/{lib/upgrade/index.js → bin/upgrade/upgrade.js} +2 -2
  45. package/{lib → bin}/upgrade/util/pom.js +2 -2
  46. package/{lib → bin}/upgrade/util/prompt.js +1 -1
  47. package/bin/util/containerize.js +8 -4
  48. package/bin/version.js +10 -1
  49. package/{lib → bin}/watch/hot-reload.js +1 -1
  50. package/bin/{watch.js → watch/index.js} +17 -9
  51. package/{lib → bin}/watch/livereload-connect.js +1 -1
  52. package/{lib → bin}/watch/vite-watch.js +1 -1
  53. package/{lib → bin}/watch/watched.js +2 -2
  54. package/lib/build/constants.js +1 -1
  55. package/lib/build/plugins/fiori/index.js +31 -2
  56. package/lib/build/plugins/internal.js +4 -2
  57. package/lib/build/plugins/mtx-sidecar/index.js +7 -8
  58. package/lib/build/plugins/nodejs/index.js +64 -7
  59. package/lib/compile/to_asyncapi.js +1 -1
  60. package/lib/env/schema.js +16 -0
  61. package/lib/env/schemas/cds-rc.js +1 -76
  62. package/lib/import/importapi.js +2 -3
  63. package/lib/import/message.js +0 -2
  64. package/lib/init/constants.js +2 -1
  65. package/lib/init/index.js +2 -2
  66. package/lib/init/merge.js +123 -280
  67. package/lib/init/plugin.js +3 -1
  68. package/lib/init/projectReader.js +22 -6
  69. package/lib/init/registries/xs-app.js +3 -5
  70. package/lib/init/template/ai/files/mta.yaml.hbs +1 -1
  71. package/lib/init/template/ai/index.js +14 -2
  72. package/lib/init/template/ams/index.js +2 -2
  73. package/lib/init/template/app-frontend/files/containerize.yaml.hbs +2 -2
  74. package/lib/init/template/app-frontend/index.js +4 -4
  75. package/lib/init/template/application-logging/index.js +2 -2
  76. package/lib/init/template/approuter/files/package.json +1 -1
  77. package/lib/init/template/approuter/index.js +8 -3
  78. package/lib/init/template/attachments/files/package.json.hbs +1 -1
  79. package/lib/init/template/attachments/index.js +2 -2
  80. package/lib/init/template/audit-logging/index.js +2 -2
  81. package/lib/init/template/cloud-logging/files/package.json.hbs +4 -4
  82. package/lib/init/template/cloud-logging/index.js +2 -2
  83. package/lib/init/template/completion/completionSetup.js +36 -39
  84. package/lib/init/template/connectivity/index.js +2 -2
  85. package/lib/init/template/data/as-csv.js +15 -5
  86. package/lib/init/template/data/as-json.js +114 -42
  87. package/lib/init/template/data/index.js +16 -2
  88. package/lib/init/template/destination/index.js +2 -2
  89. package/lib/init/template/dynatrace/files/package.json.hbs +3 -3
  90. package/lib/init/template/dynatrace/index.js +2 -2
  91. package/lib/init/template/enterprise-messaging/index.js +2 -2
  92. package/lib/init/template/enterprise-messaging-shared/index.js +2 -2
  93. package/lib/init/template/extensibility/files/mta.yaml.hbs +11 -0
  94. package/lib/init/template/extensibility/files/xs-security.json.hbs +1 -1
  95. package/lib/init/template/extensibility/index.js +3 -3
  96. package/lib/init/template/github-actions/index.js +2 -2
  97. package/lib/init/template/hana/index.js +3 -2
  98. package/lib/init/template/hana-serverless/files/db/package.json +14 -0
  99. package/lib/init/template/hana-serverless/files/identity.values.yaml.hbs +10 -0
  100. package/lib/init/template/hana-serverless/files/mta.yaml.hbs +64 -0
  101. package/lib/init/template/hana-serverless/files/package.json.hbs +35 -0
  102. package/lib/init/template/hana-serverless/files/src/.hdiconfig +139 -0
  103. package/lib/init/template/hana-serverless/files/undeploy.json +7 -0
  104. package/lib/init/template/hana-serverless/files/values.yaml.hbs +18 -0
  105. package/lib/init/template/hana-serverless/index.js +184 -0
  106. package/lib/init/template/html5-repo/files/containerize.yaml.hbs +2 -2
  107. package/lib/init/template/html5-repo/files/mta.yaml.hbs +5 -0
  108. package/lib/init/template/html5-repo/index.js +18 -14
  109. package/lib/init/template/http/index.js +123 -26
  110. package/lib/init/template/ias/index.js +2 -2
  111. package/lib/init/template/kafka/index.js +2 -2
  112. package/lib/init/template/kyma/index.js +7 -5
  113. package/lib/init/template/malware-scanner/index.js +2 -2
  114. package/lib/init/template/mta/files/mta.yaml.hbs +1 -1
  115. package/lib/init/template/multitenancy/index.js +18 -3
  116. package/lib/init/template/nodejs/index.js +4 -2
  117. package/lib/init/template/notifications/index.js +2 -2
  118. package/lib/init/template/portal/files/mta.yaml.hbs +4 -0
  119. package/lib/init/template/portal/index.js +13 -8
  120. package/lib/init/template/postgres/index.js +2 -2
  121. package/lib/init/template/redis/index.js +2 -2
  122. package/lib/init/template/sample/files/db/currencies.cds +2 -0
  123. package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Authors.csv +1 -1
  124. package/lib/init/template/tiny-sample/files/nodejs/db/data/CatalogService.Books.csv +2 -2
  125. package/lib/init/template/workzone-standard/index.js +5 -5
  126. package/lib/init/template/xsuaa/index.js +20 -2
  127. package/lib/lint/eslintHelp.json +1 -1
  128. package/lib/mtx/auth_manager.js +103 -37
  129. package/lib/mtx/params.js +3 -2
  130. package/lib/mtx/settings_manager.js +45 -28
  131. package/lib/mtx/tenant_action.js +0 -1
  132. package/lib/mtx/util/credentials.js +62 -0
  133. package/node_modules/@cap-js/openapi/lib/compile/csdl.js +3 -3
  134. package/node_modules/@cap-js/openapi/lib/compile/csdl2openapi.js +111 -103
  135. package/node_modules/@cap-js/openapi/lib/compile/diagram.js +4 -4
  136. package/node_modules/@cap-js/openapi/lib/compile/types.d.ts +3 -1
  137. package/node_modules/@cap-js/openapi/package.json +3 -3
  138. package/node_modules/@sap/cds/CHANGELOG.md +64 -0
  139. package/node_modules/@sap/cds/app/index.js +5 -4
  140. package/node_modules/@sap/cds/eslint.config.mjs +1 -0
  141. package/node_modules/@sap/cds/lib/compile/for/nodejs.js +1 -0
  142. package/node_modules/@sap/cds/lib/compile/minify.js +14 -10
  143. package/node_modules/@sap/cds/lib/env/cds-env.js +1 -1
  144. package/node_modules/@sap/cds/lib/env/cds-requires.js +22 -11
  145. package/node_modules/@sap/cds/lib/env/defaults.js +4 -1
  146. package/node_modules/@sap/cds/lib/env/schemas/cds-rc.js +5 -2
  147. package/node_modules/@sap/cds/lib/plugins.js +9 -5
  148. package/node_modules/@sap/cds/lib/req/spawn.js +1 -1
  149. package/node_modules/@sap/cds/lib/srv/srv-dispatch.js +1 -1
  150. package/node_modules/@sap/cds/lib/srv/srv-models.js +1 -1
  151. package/node_modules/@sap/cds/lib/utils/cds-utils.js +2 -1
  152. package/node_modules/@sap/cds/libx/_runtime/common/generic/assert.js +2 -3
  153. package/node_modules/@sap/cds/libx/_runtime/common/generic/auth/restrict.js +8 -1
  154. package/node_modules/@sap/cds/libx/_runtime/common/generic/crud.js +18 -8
  155. package/node_modules/@sap/cds/libx/_runtime/fiori/lean-draft.js +25 -17
  156. package/node_modules/@sap/cds/libx/_runtime/messaging/common-utils/authorizedRequest.js +3 -2
  157. package/node_modules/@sap/cds/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +9 -3
  158. package/node_modules/@sap/cds/libx/_runtime/remote/Service.js +4 -19
  159. package/node_modules/@sap/cds/libx/_runtime/remote/utils/LruCache.js +42 -0
  160. package/node_modules/@sap/cds/libx/_runtime/remote/utils/client.js +14 -4
  161. package/node_modules/@sap/cds/libx/_runtime/remote/utils/cloudSdkProvider.js +2 -9
  162. package/node_modules/@sap/cds/libx/_runtime/remote/utils/destinationClient.js +150 -0
  163. package/node_modules/@sap/cds/libx/_runtime/remote/utils/error.js +13 -0
  164. package/node_modules/@sap/cds/libx/_runtime/remote/utils/fetchClient.js +26 -18
  165. package/node_modules/@sap/cds/libx/_runtime/remote/utils/query.js +34 -23
  166. package/node_modules/@sap/cds/libx/_runtime/remote/utils/token.js +82 -0
  167. package/node_modules/@sap/cds/libx/_runtime/ucl/Service.js +36 -189
  168. package/node_modules/@sap/cds/libx/common/utils/streaming.js +16 -16
  169. package/node_modules/@sap/cds/libx/http/location.js +3 -3
  170. package/node_modules/@sap/cds/libx/odata/middleware/batch.js +16 -10
  171. package/node_modules/@sap/cds/libx/odata/middleware/metadata.js +9 -6
  172. package/node_modules/@sap/cds/libx/odata/middleware/service-document.js +1 -1
  173. package/node_modules/@sap/cds/libx/odata/parse/afterburner.js +19 -3
  174. package/node_modules/@sap/cds/libx/odata/parse/cqn2odata.js +83 -86
  175. package/node_modules/@sap/cds/libx/queue/SchedulingService.js +17 -2
  176. package/node_modules/@sap/cds/libx/queue/processing.js +1 -3
  177. package/node_modules/@sap/cds/libx/rest/RestAdapter.js +3 -7
  178. package/node_modules/@sap/cds/libx/rest/middleware/delete.js +3 -3
  179. package/node_modules/@sap/cds/libx/rest/middleware/parse.js +13 -8
  180. package/node_modules/@sap/cds/libx/rest/middleware/read.js +3 -3
  181. package/node_modules/@sap/cds/libx/rest/middleware/upsert.js +2 -2
  182. package/node_modules/@sap/cds/package.json +1 -1
  183. package/node_modules/@sap/cds-compiler/CHANGELOG.md +60 -8
  184. package/node_modules/@sap/cds-compiler/bin/cdsc.js +2 -2
  185. package/node_modules/@sap/cds-compiler/doc/IncompatibleChanges_v7.md +46 -19
  186. package/node_modules/@sap/cds-compiler/lib/api/main.js +10 -7
  187. package/node_modules/@sap/cds-compiler/lib/api/options.js +8 -2
  188. package/node_modules/@sap/cds-compiler/lib/base/csnRefs.js +5 -2
  189. package/node_modules/@sap/cds-compiler/lib/base/message-registry.js +4 -0
  190. package/node_modules/@sap/cds-compiler/lib/base/optionProcessor.js +12 -0
  191. package/node_modules/@sap/cds-compiler/lib/checks/enricher.js +1 -0
  192. package/node_modules/@sap/cds-compiler/lib/compiler/assert-consistency.js +8 -7
  193. package/node_modules/@sap/cds-compiler/lib/compiler/checks.js +3 -3
  194. package/node_modules/@sap/cds-compiler/lib/compiler/define.js +301 -75
  195. package/node_modules/@sap/cds-compiler/lib/compiler/dictionaries.js +2 -0
  196. package/node_modules/@sap/cds-compiler/lib/compiler/extend.js +40 -26
  197. package/node_modules/@sap/cds-compiler/lib/compiler/populate.js +45 -60
  198. package/node_modules/@sap/cds-compiler/lib/compiler/propagator.js +16 -7
  199. package/node_modules/@sap/cds-compiler/lib/compiler/resolve.js +41 -15
  200. package/node_modules/@sap/cds-compiler/lib/compiler/shared.js +7 -6
  201. package/node_modules/@sap/cds-compiler/lib/compiler/tweak-assocs.js +62 -50
  202. package/node_modules/@sap/cds-compiler/lib/compiler/utils.js +29 -14
  203. package/node_modules/@sap/cds-compiler/lib/edm/edmAnnoPreprocessor.js +6 -5
  204. package/node_modules/@sap/cds-compiler/lib/gen/CdlGrammar.checksum +1 -1
  205. package/node_modules/@sap/cds-compiler/lib/gen/CdlParser.js +1119 -1109
  206. package/node_modules/@sap/cds-compiler/lib/gen/Dictionary.json +19 -3
  207. package/node_modules/@sap/cds-compiler/lib/json/from-csn.js +10 -16
  208. package/node_modules/@sap/cds-compiler/lib/json/to-csn.js +58 -39
  209. package/node_modules/@sap/cds-compiler/lib/main.d.ts +8 -0
  210. package/node_modules/@sap/cds-compiler/lib/main.js +1 -0
  211. package/node_modules/@sap/cds-compiler/lib/model/csnUtils.js +2 -0
  212. package/node_modules/@sap/cds-compiler/lib/parsers/AstBuildingParser.js +2 -1
  213. package/node_modules/@sap/cds-compiler/lib/parsers/XprTree.js +8 -0
  214. package/node_modules/@sap/cds-compiler/lib/render/toCdl.js +22 -1
  215. package/node_modules/@sap/cds-compiler/lib/render/toSql.js +17 -2
  216. package/node_modules/@sap/cds-compiler/lib/render/utils/common.js +6 -1
  217. package/node_modules/@sap/cds-compiler/lib/render/utils/operators.js +27 -0
  218. package/node_modules/@sap/cds-compiler/lib/render/utils/standardDatabaseFunctions.js +125 -3
  219. package/node_modules/@sap/cds-compiler/lib/tool-lib/revealInternalProperties.js +2 -1
  220. package/node_modules/@sap/cds-compiler/lib/transform/db/applyTransformations.js +3 -0
  221. package/node_modules/@sap/cds-compiler/lib/transform/db/associations.js +8 -2
  222. package/node_modules/@sap/cds-compiler/lib/transform/db/backlinks.js +22 -6
  223. package/node_modules/@sap/cds-compiler/lib/transform/db/constraints.js +62 -1
  224. package/node_modules/@sap/cds-compiler/lib/transform/effective/annotations.js +40 -0
  225. package/node_modules/@sap/cds-compiler/lib/transform/effective/main.js +1 -0
  226. package/node_modules/@sap/cds-compiler/lib/transform/forRelationalDB.js +6 -1
  227. package/node_modules/@sap/cds-compiler/lib/transform/translateAssocsToJoins.js +19 -8
  228. package/node_modules/@sap/cds-compiler/package.json +1 -1
  229. package/node_modules/@sap/cds-mtxs/CHANGELOG.md +51 -0
  230. package/node_modules/@sap/cds-mtxs/bin/cds-mtx-migrate.js +32 -48
  231. package/node_modules/@sap/cds-mtxs/bin/cds-mtx.js +35 -16
  232. package/node_modules/@sap/cds-mtxs/cds-plugin.js +18 -0
  233. package/node_modules/@sap/cds-mtxs/lib/migration/migration.js +3 -408
  234. package/node_modules/@sap/cds-mtxs/lib/utils.js +19 -4
  235. package/node_modules/@sap/cds-mtxs/package.json +1 -1
  236. package/node_modules/@sap/cds-mtxs/srv/cf/abstract-provisioning-service.js +6 -7
  237. package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/annotations.js +5 -2
  238. package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/index.js +6 -5
  239. package/node_modules/@sap/cds-mtxs/srv/extensibility-service.cds +0 -11
  240. package/node_modules/@sap/cds-mtxs/srv/extensibility-service.js +34 -35
  241. package/node_modules/@sap/cds-mtxs/srv/jobs-service.js +30 -24
  242. package/node_modules/@sap/cds-mtxs/srv/model-provider.js +19 -4
  243. package/node_modules/@sap/cds-mtxs/srv/plugins/hana/ctnr-mgr-base.js +6 -3
  244. package/node_modules/@sap/cds-mtxs/srv/plugins/hana/hdi.js +5 -3
  245. package/node_modules/@sap/cds-mtxs/srv/plugins/hana/srv-mgr.js +3 -2
  246. package/node_modules/@sap/cds-mtxs/srv/plugins/hana/tms.js +17 -0
  247. package/node_modules/@sap/cds-mtxs/srv/plugins/hana.js +18 -21
  248. package/node_modules/@sap/xsenv/CHANGELOG.md +7 -0
  249. package/node_modules/@sap/xsenv/package.json +10 -7
  250. package/node_modules/body-parser/node_modules/content-type/README.md +2 -0
  251. package/node_modules/body-parser/node_modules/content-type/dist/index.d.ts +20 -0
  252. package/node_modules/body-parser/node_modules/content-type/dist/index.js +20 -14
  253. package/node_modules/body-parser/node_modules/content-type/dist/index.js.map +1 -1
  254. package/node_modules/body-parser/node_modules/content-type/package.json +1 -1
  255. package/node_modules/hdb/cfg/VERSION +1 -1
  256. package/node_modules/hdb/lib/protocol/ClientInfo.js +16 -3
  257. package/node_modules/hdb/lib/protocol/Connection.js +1 -0
  258. package/node_modules/hdb/package.json +3 -2
  259. package/node_modules/negotiator/lib/accept.js +54 -0
  260. package/node_modules/negotiator/lib/charset.js +10 -34
  261. package/node_modules/negotiator/lib/encoding.js +9 -30
  262. package/node_modules/negotiator/lib/language.js +15 -36
  263. package/node_modules/negotiator/lib/mediaType.js +16 -134
  264. package/node_modules/negotiator/node_modules/content-type/LICENSE +22 -0
  265. package/node_modules/negotiator/node_modules/content-type/README.md +71 -0
  266. package/node_modules/negotiator/node_modules/content-type/dist/index.d.ts +46 -0
  267. package/node_modules/negotiator/node_modules/content-type/dist/index.js +176 -0
  268. package/node_modules/negotiator/node_modules/content-type/dist/index.js.map +1 -0
  269. package/node_modules/negotiator/node_modules/content-type/package.json +52 -0
  270. package/node_modules/negotiator/package.json +16 -10
  271. package/node_modules/qs/.github/THREAT_MODEL.md +3 -3
  272. package/node_modules/qs/CHANGELOG.md +15 -0
  273. package/node_modules/qs/README.md +19 -1
  274. package/node_modules/qs/dist/qs.js +21 -21
  275. package/node_modules/qs/eslint.config.mjs +1 -1
  276. package/node_modules/qs/lib/parse.js +3 -4
  277. package/node_modules/qs/lib/stringify.js +23 -8
  278. package/node_modules/qs/lib/utils.js +10 -3
  279. package/node_modules/qs/package.json +4 -4
  280. package/node_modules/qs/test/parse.js +192 -3
  281. package/node_modules/qs/test/stringify.js +317 -0
  282. package/node_modules/qs/test/utils.js +12 -0
  283. package/node_modules/sax/lib/sax.js +27 -9
  284. package/node_modules/sax/package.json +1 -1
  285. package/node_modules/type-is/node_modules/content-type/README.md +2 -0
  286. package/node_modules/type-is/node_modules/content-type/dist/index.d.ts +20 -0
  287. package/node_modules/type-is/node_modules/content-type/dist/index.js +20 -14
  288. package/node_modules/type-is/node_modules/content-type/dist/index.js.map +1 -1
  289. package/node_modules/type-is/node_modules/content-type/package.json +1 -1
  290. package/node_modules/ws/lib/permessage-deflate.js +3 -1
  291. package/node_modules/ws/package.json +1 -1
  292. package/package.json +5 -5
  293. package/bin/completion/scripts/cds-bash.sh +0 -20
  294. package/bin/completion/scripts/cds-fish.fish +0 -13
  295. package/bin/completion/scripts/cds-ps.ps1 +0 -19
  296. package/bin/completion/scripts/cds-zsh.sh +0 -13
  297. package/lib/deploy/index.js +0 -25
  298. package/lib/import/asyncapi/importAsyncAPI.js +0 -33
  299. package/lib/import/asyncapi/index.js +0 -18
  300. package/lib/import/asyncapi/parserContext.js +0 -372
  301. package/lib/import/asyncapi/utils.js +0 -49
  302. package/lib/init/template/nodejs/files/.gitignore.hbs +0 -34
  303. package/node_modules/@sap/cds/libx/_runtime/ucl/queries.js +0 -61
  304. package/node_modules/@sap/cds-mtxs/lib/migration/extension-project-builder.js +0 -129
  305. package/node_modules/@sap/cds-mtxs/lib/migration/extension-project.js +0 -89
  306. package/node_modules/@sap/cds-mtxs/lib/migration/mtx-adapter.js +0 -230
  307. package/node_modules/negotiator/HISTORY.md +0 -114
  308. /package/{lib → bin}/upgrade/context.js +0 -0
  309. /package/{lib → bin}/upgrade/migrations/cds10/migrations.json +0 -0
  310. /package/{lib → bin}/upgrade/preflight/cds-version.js +0 -0
  311. /package/{lib → bin}/upgrade/preflight/project-type.js +0 -0
  312. /package/{lib → bin}/upgrade/steps/analyze/classification.js +0 -0
  313. /package/{lib → bin}/upgrade/steps/analyze/detector.js +0 -0
  314. /package/{lib → bin}/upgrade/steps/analyze/evaluator.js +0 -0
  315. /package/{lib → bin}/upgrade/steps/analyze/reporter.js +0 -0
  316. /package/{lib → bin}/upgrade/steps/analyze/setup.js +0 -0
  317. /package/{lib → bin}/upgrade/steps/analyze/utils/detection.js +0 -0
  318. /package/{lib → bin}/upgrade/steps/analyze/utils/files.js +0 -0
  319. /package/{lib → bin}/upgrade/steps/analyze/utils/grep.js +0 -0
  320. /package/{lib → bin}/upgrade/steps/analyze/utils/yaml.js +0 -0
  321. /package/{lib → bin}/upgrade/util/workspaces.js +0 -0
  322. /package/{lib → bin}/watch/esm-resolve-registration.js +0 -0
  323. /package/{lib → bin}/watch/livereload-server.js +0 -0
  324. /package/{lib → bin}/watch/node-watch.js +0 -0
  325. /package/{lib → bin}/watch/open.js +0 -0
  326. /package/{lib → bin}/watch/watcher.js +0 -0
@@ -1,12 +1,6 @@
1
- const path = require('path')
2
- const mtxAdapter = require('./mtx-adapter')
3
- const { createProjects } = require('./extension-project')
4
1
  const cds = require('@sap/cds')
5
- const LOG = cds.log('mtx'), DEBUG = cds.debug('mtx')
6
- const { mkdirp, rimraf, tar, exists, readdir, read, write, isdir, isfile } = cds.utils
7
- const fs = cds.utils.fs.promises
2
+ const LOG = cds.log('mtx')
8
3
 
9
- const linter = require('../../srv/extensibility/linter')
10
4
  const { t0_ } = require('../utils')
11
5
  const Tenants = 'cds.xt.Tenants'
12
6
 
@@ -14,14 +8,6 @@ const Tenants = 'cds.xt.Tenants'
14
8
  module.exports._hasMtEnv = () => cds.requires.multitenancy || (cds.env.requires['cds.xt.DeploymentService'] && cds.env.requires['cds.xt.ModelProviderService'])
15
9
  module.exports._hasExtensibilityEnv = () => cds.requires.extensibility || cds.env.requires['cds.xt.ExtensibilityService']
16
10
 
17
- module.exports._getExtensionProjectDirectory = function(dir) {
18
- if (dir) {
19
- LOG.log('Project directory', dir, 'does not exist.', dir, 'has been created.')
20
- return mkdirp(dir)
21
- }
22
- return mtxAdapter.mkdirTemp()
23
- }
24
-
25
11
  class MigrationResult {
26
12
  constructor() {
27
13
  this.connectedTenants = []
@@ -29,9 +15,8 @@ class MigrationResult {
29
15
  this.hasError = false
30
16
  }
31
17
 
32
- addTenant(tenant, meta = true) {
18
+ addTenant(tenant) {
33
19
  this.connectedTenants.push(tenant)
34
- if (meta) this.connectedTenants.push(mtxAdapter.getMetaTenantName(tenant))
35
20
  }
36
21
 
37
22
  log(tenant, message) {
@@ -59,17 +44,13 @@ function getT0() {
59
44
  return cds.env.requires.multitenancy?.t0 ?? 't0'
60
45
  }
61
46
 
62
- module.exports.getDbId = async function () {
63
- return mtxAdapter.getDbId()
64
- }
65
-
66
47
  module.exports.syncTenantList = async function syncTenantList(tenants, options, deleteEntries = false) {
67
48
  const EXCLUDED_TENANTS = /^MT_LIB_TENANT-.*/
68
49
 
69
50
  const migrationResult = new MigrationResult()
70
51
  const { dry, force } = options
71
52
  const t0 = getT0()
72
- migrationResult.addTenant(t0, false) // adds tenant for disconnect
53
+ migrationResult.addTenant(t0) // adds tenant for disconnect
73
54
 
74
55
  // get all containers + create metadata in t0
75
56
  const ds = await cds.connect.to('cds.xt.DeploymentService')
@@ -96,390 +77,4 @@ module.exports.syncTenantList = async function syncTenantList(tenants, options,
96
77
  }
97
78
  migrationResult.log(t0, `Tenant list created for ${JSON.stringify(tenantContainers)} ${dry ? '(dry run only)' : ''}.`)
98
79
  return migrationResult
99
- }
100
-
101
- module.exports.cleanupMetatenants = async function cleanup(tenants, options) {
102
- const migrationResult = new MigrationResult()
103
- const { dry } = options
104
-
105
- let tenantsToCleanup = tenants
106
- // handle tenant "*" -> retrieve all tenants
107
- if (tenants.includes('*')) {
108
- tenantsToCleanup = await mtxAdapter.getAllTenantIds()
109
- }
110
-
111
- const t0 = getT0()
112
- migrationResult.addTenant(t0, false) // adds tenant for disconnect
113
-
114
- const metatenantsToCleanup = {}
115
- for (const tenant of tenantsToCleanup) {
116
- if (tenant === t0) continue
117
- const metatenant = mtxAdapter.getMetaTenantName(tenant)
118
- metatenantsToCleanup[tenant] = metatenant
119
- }
120
-
121
- for (const [tenant, metatenant] of Object.entries(metatenantsToCleanup)) {
122
- migrationResult.addTenant(metatenant, false)
123
-
124
- try {
125
- // check if tenant was already migrated
126
- try {
127
- const migrated = tenant !== '__META__' ? await mtxAdapter.isMigrated(tenant) : { timestamp: true }
128
- if (!migrated.timestamp) {
129
- migrationResult.error(tenant, `Tenant ${tenant} was not migrated. Skipping cleanup.`, new Error(`Tenant ${tenant} was not migrated`))
130
- continue
131
- }
132
- } catch (e) {
133
- if (e.status === 404) {
134
- migrationResult.log(tenant, `No @sap/cds-mtx meta-tenant found for ${tenant}. Skipping cleanup.`)
135
- continue
136
- } else throw e
137
- }
138
-
139
- // do the cleanup
140
- if (!dry) {
141
- const ds = await cds.connect.to('cds.xt.DeploymentService')
142
- await ds.unsubscribe(metatenant)
143
- }
144
- migrationResult.log(metatenant, `Metatenant ${metatenant} successfully deleted.`)
145
- } catch (error) {
146
- migrationResult.error(metatenant, `Cleanup of tenant ${metatenant} failed.`, error)
147
- continue
148
- }
149
- }
150
-
151
- // only cleanup __META__ if all other meta tenants have been cleaned up successfully
152
- if (!dry && tenants.includes('*') && !migrationResult.hasError) {
153
- const ds = await cds.connect.to('cds.xt.DeploymentService')
154
- const commonMetaTenant = '__META__'
155
- await ds.unsubscribe(commonMetaTenant)
156
- migrationResult.log(commonMetaTenant, `Common metatenant ${commonMetaTenant} successfully deleted.`)
157
- }
158
-
159
- LOG.log('Cleanup done')
160
- return migrationResult
161
- }
162
-
163
- module.exports.checkMigration = async function checkMigration(req) {
164
- const { tenant } = req.data
165
- if (await mtxAdapter.hasExtensions(tenant)) {
166
- if (module.exports._hasExtensibilityEnv()) {
167
- if (!await mtxAdapter.isMigrated(tenant))
168
- req.reject(422, `Upgrade of tenant ${tenant} aborted. Extensions have not been migrated yet`)
169
- } else {
170
- req.reject(422, `Upgrade of tenant ${tenant} aborted. Old MTX Extensions exist but extensibility is not configured (cds.requires.extensibility is false)`)
171
- }
172
- }
173
- }
174
-
175
- module.exports.getMissingMtxTenants = async (existingTenants) => {
176
- if (await mtxAdapter.wasOldMtx()) {
177
- // TODO do this only once
178
- // get all mtx tenants
179
- const mtxTenants = await mtxAdapter.getAllTenantIds()
180
- // add metadata for non-existing entries
181
- return await Promise.all(mtxTenants.filter( mtxTenant => !existingTenants.includes(mtxTenant)).map( async mtxTenant => {
182
- await module.exports.addMetadata(mtxTenant, {
183
- subscribedTenantId: mtxTenant
184
- })
185
- return mtxTenant
186
- }))
187
- }
188
- return []
189
- }
190
-
191
- module.exports.migrate = async function migrate(tenants, options) {
192
-
193
- const { directory, dry, force, tagRule, tag: defaultTag, "skip-verification": skipVerification} = options
194
-
195
- const migrationResult = new MigrationResult()
196
- let tenantsToMigrate = tenants
197
-
198
- // handle tenant "*" -> retrieve all tenants
199
- if (tenants.includes('*')) {
200
- tenantsToMigrate = await mtxAdapter.getAllTenantIds()
201
- }
202
-
203
- const t0 = getT0()
204
- migrationResult.addTenant(t0, false) // adds tenant for disconnect
205
-
206
- const extensibility = module.exports._hasExtensibilityEnv()
207
- let projectsDir
208
-
209
- for (const tenant of tenantsToMigrate) {
210
-
211
- migrationResult.addTenant(tenant)
212
-
213
- // skip migration of t0
214
- if (tenant === t0) {
215
- migrationResult.log(tenant, `Skipping internal tenant ${tenant}.`)
216
- continue
217
- }
218
-
219
- try {
220
- // check if tenant was already migrated
221
- try {
222
- const migrated = await mtxAdapter.isMigrated(tenant)
223
- if (migrated?.timestamp && !force) {
224
- migrationResult.log(tenant, `Tenant ${tenant} is already migrated. Skipping migration.`)
225
- continue
226
- }
227
- } catch (e) {
228
- if (e.status === 404) {
229
- migrationResult.log(tenant, `No @sap/cds-mtx meta-tenant found for ${tenant}. Skipping migration.`)
230
- continue
231
- } else throw e
232
- }
233
-
234
- // Get from old mtx
235
- const metadata = await mtxAdapter.getMetadata(tenant)
236
-
237
- if (extensibility) {
238
-
239
- // update tenant metadata + extension tables
240
- // add extension tables - TODO could also be done on-the-fly with push
241
- const extTables = await cds.load(`${__dirname}/../../db/extensions.cds`)
242
- cds.model = cds.db.model = cds.compile.for.nodejs(extTables)
243
- if (!dry) {
244
- // disable extension deployment to avoid lengthy redeployments when doing the push()
245
- const ds = await cds.connect.to('cds.xt.DeploymentService')
246
- ds.prepend (srv => srv.on ('extend', () => { }))
247
-
248
- try {
249
- await cds.tx({ tenant}, tx => tx.run(SELECT.one(1).from('cds.xt.Extensions')))
250
- // add metadata in case it had not been added before
251
- await module.exports.addMetadata(tenant, metadata)
252
- } catch (error) {
253
- LOG.log('cds.xt.Extensions not yet deployed, deploying ...')
254
- DEBUG && DEBUG(error)
255
- await ds.subscribe({ tenant, metadata, options: { csn: extTables } }) // also creates metadata ...
256
- }
257
- }
258
-
259
- // run extend -> into memory?
260
- const mtxExtension = await mtxAdapter.getExtension(tenant)
261
-
262
- if (mtxExtension) {
263
- // allow different folder from command line to preserve results
264
- projectsDir = projectsDir || await module.exports._getExtensionProjectDirectory(directory)
265
- const tenantProjectFolder = path.join(projectsDir, tenant)
266
-
267
- const tags = await createProjects(mtxExtension, tenantProjectFolder, tagRule, defaultTag)
268
-
269
- // upload and verify extensions
270
- // iterate all tags
271
- migrationResult.log(tenant, `Created projects for tags "${tags}"`)
272
-
273
- // Verify migrated extension
274
- if (!skipVerification) {
275
- try {
276
- // check diff and abort if necessary
277
- const existingCsn = await mtxAdapter.getCsn(tenant)
278
-
279
- await fs.mkdir(path.join(tenantProjectFolder, 'mtx_original_csn'), { recursive: true })
280
- await fs.writeFile(path.join(tenantProjectFolder, 'mtx_original_csn', 'csn.json'), JSON.stringify(existingCsn, null, 2))
281
-
282
- await _verifyExtension(migrationResult, tenantProjectFolder, tenant, tags, existingCsn, options)
283
- migrationResult.log(tenant, `Extension verification successful for tenant ${tenant} [${tenantProjectFolder}]`)
284
- } catch (error) {
285
- migrationResult.error(tenant, `Extension verification failed for tenant ${tenant} [${tenantProjectFolder}]), skipping migration.`, error)
286
- continue
287
- }
288
- } else {
289
- migrationResult.log(tenant, `Extension verification skipped for tenant ${tenant}`)
290
- }
291
-
292
- if (!dry && force) {
293
- // cleanup in case extension ids have changed
294
- if (tenant) cds.context = { tenant }
295
- await DELETE.from('cds.xt.Extensions')
296
- }
297
-
298
- for (const tag of tags) {
299
- const projectFolder = path.join(tenantProjectFolder, tag)
300
-
301
- if (!dry) {
302
- try {
303
- const extensionTgz = await fs.readFile(path.join(projectFolder, 'gen', 'extension.tgz'))
304
- const es = await cds.connect.to('cds.xt.ExtensibilityService')
305
- await es.tx({ tenant, user: new cds.User.Privileged }, tx =>
306
- tx.push(extensionTgz.toString('base64'), tag)
307
- )
308
- migrationResult.log(tenant, `Extension for tenant ${tenant} and tag ${tag} pushed.`)
309
- } catch (error) {
310
- migrationResult.error(tenant, `Error pushing extension for tenant ${tenant} and tag ${tag}`, error)
311
- continue
312
- }
313
- }
314
- }
315
- }
316
- } else {
317
- // check if extensions exist -> abort if yes
318
- if (await mtxAdapter.hasExtensions(tenant)) throw new Error(`Extensions exist but extensibility is not configured (cds.requires.extensibilty is false)`)
319
-
320
- if (!dry) {
321
- await module.exports.addMetadata(tenant, metadata)
322
- migrationResult.log(tenant, `Metadata for tenant ${tenant} added.`)
323
- }
324
- }
325
-
326
- if (!dry) await mtxAdapter.setMigrated(tenant, tagRule, defaultTag, !!force /* ensure it is not undefined so that a record is written */)
327
- migrationResult.log(tenant, `Migration of tenant ${tenant} done.`)
328
- } catch (error) {
329
- migrationResult.error(tenant, `Migration of tenant ${tenant} failed.`, error)
330
- }
331
- }
332
-
333
- // cleanup tmpdir, keep directory if it was set externally
334
- if (!directory && projectsDir) await fs.rm(projectsDir, { recursive: true, force: true })
335
-
336
- LOG.log('Extension migration done')
337
- return migrationResult
338
- }
339
-
340
- module.exports.addMetadata = async function addMetadata(tenant, metadata) {
341
- try {
342
- // can't use UPSERT here so @cds.on.insert still works for createdAt
343
- await t0_(INSERT.into('cds.xt.Tenants', { ID: tenant, metadata: JSON.stringify(metadata) }))
344
- } catch (e) {
345
- if (e.message === 'ENTITY_ALREADY_EXISTS' || e.code === 301 || e.message.match(/unique constraint/i)) {
346
- await t0_(UPSERT.into('cds.xt.Tenants', { ID: tenant, metadata: JSON.stringify(metadata) }))
347
- } else throw e
348
- }
349
- }
350
-
351
- async function _verifyExtension(migrationResult, tenantProjectFolder, tenant, tags, existingCsn, options) {
352
-
353
- const { "ignore-migrations": ignoreMigrations } = options
354
-
355
- const projectFolders = tags
356
-
357
- const mp = await cds.connect.to('cds.xt.ModelProviderService')
358
- const mainCsn = await mp.getCsn({ tenant, flavor: 'inferred', activated: true, base: true, options: { skipMinify: true } })
359
-
360
- if (!mainCsn) throw new Error(`Verification error for tenant ${tenant}: Empty base model`)
361
-
362
- let previewCsn = mainCsn
363
-
364
- // calculate model with extensions to be pushed later
365
- for (const projectFolder of projectFolders) {
366
- const extensionCsnString = await fs.readFile(path.join(tenantProjectFolder, projectFolder, 'gen', 'ext', 'extension.csn'))
367
- const extensionCsn = JSON.parse(extensionCsnString)
368
- previewCsn = cds.extend(previewCsn).with(extensionCsn)
369
- }
370
-
371
- // ensure flavor
372
- const inferredExistingCsn = cds.compile({inferred: existingCsn}, {flavor: 'inferred'})
373
-
374
- const existingHana = cds.compiler.to.hdi.migration(inferredExistingCsn)
375
- const newHana = cds.compiler.to.hdi.migration(previewCsn)
376
-
377
- const diffMessages = []
378
-
379
- // are artifacts lost?
380
- const hanaDiffNewToOld = cds.compiler.to.hdi.migration(cds.minify(previewCsn), {}, cds.minify(existingHana.afterImage))
381
- if (hanaDiffNewToOld.deletions.length) {
382
- diffMessages.push(`Migrated model is missing artifacts:\n ${hanaDiffNewToOld.deletions.map( ({ name, suffix }) => `${name}${suffix}\n`)}`)
383
- }
384
-
385
- if (hanaDiffNewToOld.migrations.length) {
386
- const ignore = ignoreMigrations ?? '^sap.common'
387
- const relevantMigrations = hanaDiffNewToOld.migrations.filter( m => !new RegExp(ignore).test(m.name))
388
- migrationResult.log(tenant, `Table migrations found but ignored for /${ignore}/`)
389
-
390
- if (relevantMigrations.length) diffMessages.push(`Table migrations found\n` +
391
- `${relevantMigrations.map( ({ name, suffix, changeset }) => ` ${name}${suffix}: ${changeset.map(({sql}) => sql)}\n`)}`)
392
- }
393
-
394
- // does the new model contain more artifacts?
395
- const MTXS_ENTITIES = ['cds.xt.Extensions']
396
- const hanaDiffOldToNew = cds.compiler.to.hdi.migration(cds.minify(inferredExistingCsn), {}, cds.minify(newHana.afterImage)) // cds.xt.Extensions is allowed
397
- const filteredDeletions = hanaDiffOldToNew.deletions.filter( ({name}) => !MTXS_ENTITIES.includes(name))
398
- if (filteredDeletions.length) {
399
- diffMessages.push(`Migrated model has additional artifacts:\n ${hanaDiffOldToNew.deletions.map( ({ name, suffix }) => `${name}${suffix}\n`)}`)
400
- throw new Error(`Verification error for tenant ${tenant}: migrated model has additional artifacts:\n ${hanaDiffOldToNew.deletions.map( ({ name, suffix }) => `${name}${suffix}\n`)}`)
401
- }
402
-
403
- if (diffMessages.length) throw new Error(`Verification error for tenant ${tenant}:\n${diffMessages.join('\n')}`)
404
- }
405
-
406
- module.exports.getMigratedProjects = async (req, tagRule, defaultTag, tenant) => {
407
- const temp = await mtxAdapter.mkdirTemp()
408
-
409
- let parameters = { tagRule, defaultTag }
410
- if (!(tagRule || defaultTag)) {
411
- try {
412
- const storedParameters = await mtxAdapter.getMigrationParameters(tenant) ?? {}
413
- parameters = { ...parameters, ...storedParameters }
414
- } catch (e) {
415
- req.reject(404, `No migrated projects found for tenant ${tenant}: ${e.message}`)
416
- }
417
- }
418
-
419
- // run dry migration with force + own temp directory
420
- // { directory, dry, force, tagRule: tagRegex, tag: defaultTag, "skip-verification": skipVerification, "ignore-migrations": ignoreMigrations }
421
- await module.exports.migrate([tenant], { directory: temp, dry: true, skipVerification: true, tagRule: parameters.tagRule, tag: parameters.defaultTag, force: true})
422
-
423
- const projectsLocation = path.join(temp, tenant)
424
- if (!exists(projectsLocation)) req.reject(404, `No migrated projects found for tenant ${tenant}`)
425
-
426
- // postprocessing: remove cds-based base model, adjust references
427
- await module.exports.fixBaseModelReferences(projectsLocation)
428
-
429
- try {
430
- return await tar.cz(projectsLocation)
431
- } finally {
432
- rimraf(temp)
433
- }
434
- }
435
-
436
- module.exports.fixBaseModelReferences = async (directory) => {
437
-
438
- await traverse(directory, async (file) => {
439
- // remove base cds files
440
- if (/.*\/node_modules\/_base\//.test(file)) {
441
- await rimraf(file)
442
- }
443
-
444
- // remove gen folder
445
- if (new RegExp(`${directory}/.*/gen$`).test(file)) {
446
- await rimraf(file)
447
- }
448
-
449
- // fix using statements
450
- if (/.*\.cds$/.test(file) && isfile(file)) {
451
- const content = await read(file, 'utf-8')
452
- const fixedContent = content.replace(/'_base\/.*'/g, '\'_base\'')
453
- await write(file, fixedContent, 'utf-8')
454
- }
455
- })
456
-
457
- // add index.csn and .cdsrc.json
458
- await traverse(directory, async (file) => {
459
- if (/.*\/node_modules\/_base$/.test(file)) {
460
- await addBaseAndConfig(file)
461
- }
462
- })
463
-
464
- async function traverse(dir, visitor) {
465
- const list = await readdir(dir)
466
- for (const entry of list) {
467
- const fullPath = path.join(dir, entry)
468
- await visitor(fullPath)
469
- if (await isdir(fullPath)) {
470
- await traverse(fullPath, visitor)
471
- }
472
- }
473
- }
474
- }
475
-
476
- const addBaseAndConfig = async function (directory) {
477
- const { 'cds.xt.ModelProviderService': mps } = cds.services
478
- const csn = await mps.getCsn({
479
- base: true, // without any custom extensions
480
- flavor: 'xtended'
481
- })
482
- await write(path.join(directory, 'index.csn'), cds.compile.to.json(csn))
483
- const config = linter.configCopyFrom(cds.env)
484
- await write(path.join(directory, '.cdsrc.json'), JSON.stringify(config, null, 2))
485
80
  }
@@ -89,13 +89,27 @@ const t0_ = async (query) => retry(async () => {
89
89
  return cds.tx({ tenant: t0 }, tx => { tx.model = _t0Csn; return tx.run(query) })
90
90
  })
91
91
 
92
+ const SUBDOMAIN_RE = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i
93
+
94
+ function authUrl(baseUrl, subdomain, pathname) {
95
+ const u = new URL(baseUrl)
96
+ if (subdomain) {
97
+ if (typeof subdomain !== 'string' || !SUBDOMAIN_RE.test(subdomain)) {
98
+ throw cds.error('invalid subdomain', { status: 400 })
99
+ }
100
+ const dot = u.hostname.indexOf('.')
101
+ u.hostname = subdomain + (dot >= 0 ? u.hostname.slice(dot) : '')
102
+ }
103
+ u.pathname = pathname
104
+ return u
105
+ }
106
+
92
107
  async function token(credentials, { query = {}, form = {}, subdomain } = {}) {
93
108
  const { clientid, clientsecret, certurl, url, certificate, key } = credentials ?? {}
94
- const u = new URL(certurl || url)
95
- if (subdomain) u.hostname = u.hostname.replace(/^[^.]+/, subdomain)
96
- u.pathname = '/oauth/token'
109
+ if (!form.grant_type) throw cds.error('grant_type is required', { status: 400 })
110
+ const u = authUrl(certurl || url, subdomain, '/oauth/token')
97
111
  Object.entries(query).forEach(([k, v]) => u.searchParams.append(k, v))
98
- const body = new URLSearchParams({ grant_type: 'client_credentials', client_id: clientid, ...form })
112
+ const body = new URLSearchParams({ client_id: clientid, ...form })
99
113
  const headers = { 'Content-Type': 'application/x-www-form-urlencoded', Accept: 'application/json' }
100
114
  let raw
101
115
  if (certificate) {
@@ -249,6 +263,7 @@ module.exports = {
249
263
  readData,
250
264
  readDataCsv,
251
265
  token,
266
+ authUrl,
252
267
  fetchResiliently,
253
268
  getAppId,
254
269
  deepMerge
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sap/cds-mtxs",
3
- "version": "3.9.5",
3
+ "version": "4.0.3",
4
4
  "description": "SAP Cloud Application Programming Model - Multitenancy library",
5
5
  "homepage": "https://cap.cloud.sap/",
6
6
  "keywords": [
@@ -2,7 +2,6 @@ const cds = require('@sap/cds/lib')
2
2
  const LOG = cds.log('mtx'), DEBUG = cds.debug('mtx')
3
3
  const main = require('../config')
4
4
  const { fetchResiliently, token } = require('../../lib/utils')
5
- const migration = require('../../lib/migration/migration')
6
5
  const DeploymentService = 'cds.xt.DeploymentService'
7
6
  const JobsService = 'cds.xt.JobsService'
8
7
  const Tenants = 'cds.xt.Tenants'
@@ -89,6 +88,7 @@ module.exports = class ProvisioningService extends cds.ApplicationService {
89
88
 
90
89
 
91
90
  _toMetadataJson(metadata, subscribedTenantId) {
91
+ if (!metadata) return { subscribedTenantId };
92
92
  try {
93
93
  return JSON.parse(metadata);
94
94
  } catch (error) {
@@ -114,9 +114,7 @@ module.exports = class ProvisioningService extends cds.ApplicationService {
114
114
 
115
115
  async _getTenants() {
116
116
  const ds = await cds.connect.to(DeploymentService)
117
- const tenants = await ds.getTenants()
118
- const mtxTenants = await migration.getMissingMtxTenants(tenants)
119
- const all = [...tenants, ...mtxTenants]
117
+ const all = await ds.getTenants()
120
118
  if (cds.env.requires[this.name]?.upgrade?.ignoreNonExistingContainers) {
121
119
  const containers = await ds.getContainers()
122
120
  return all.filter(t => containers.includes(t))
@@ -140,12 +138,13 @@ module.exports = class ProvisioningService extends cds.ApplicationService {
140
138
  await resources4(out)
141
139
  await csvs4('base', out)
142
140
  }
143
- const { clusterSize = 1 } = cds.env.requires.multitenancy.jobs ?? cds.env.requires[this.name]?.jobs ?? {}
144
141
  const { 'cds.xt.DeploymentService': ds } = cds.services
142
+ const js = await cds.connect.to(JobsService)
143
+ const { clusterSize = 3 } = js._config()
145
144
  const dbToTenants = (clusterSize > 1 && ds) ? await ds.tenantsByDb(tenants) : [new Set(tenants)]
146
145
  LOG.info('upgrading', { tenants })
147
146
 
148
- const js = await cds.connect.to(JobsService)
147
+
149
148
  return await new Promise((resolve, reject) => {
150
149
  const tx = js.tx({ tenant: cds.context.tenant, user: new cds.User.Privileged() })
151
150
  const job = tx.enqueue(DeploymentService, 'upgrade', dbToTenants, { options }, async error => {
@@ -292,7 +291,7 @@ module.exports = class ProvisioningService extends cds.ApplicationService {
292
291
  async _token() {
293
292
  const serviceName = 'cds.xt.' + this.constructor.name
294
293
  const cred = this._getCredentials()
295
- const raw = await token(cred, { query: { response_type: 'token' } })
294
+ const raw = await token(cred, { query: { response_type: 'token' }, form: { grant_type: 'client_credentials' } })
296
295
  const { access_token } = JSON.parse(raw)
297
296
  if (!access_token) cds.error(`could not get token for ${serviceName}: token is empty`)
298
297
  return access_token
@@ -8,6 +8,7 @@ const checkedExtensionAnnotations = new Map([
8
8
  ['@cds.persistence.journal', _createJournalAnnotationWarning],
9
9
  ['@mandatory', _createMandatoryAnnotationWarning],
10
10
  ['@readonly', _createMandatoryAnnotationWarning],
11
+ ['@Common.FieldControl', _createMandatoryAnnotationWarning],
11
12
  ['@assert.notNull', _createMandatoryAnnotationWarning],
12
13
  ['@assert.range', _createMandatoryAnnotationWarning]
13
14
  ])
@@ -18,6 +19,7 @@ const criticalExtensionAnnotations = new RegExp('^@(?:'
18
19
  + '|restrict'
19
20
  + '|readonly'
20
21
  + '|mandatory'
22
+ + '|Common\\.FieldControl'
21
23
  + '|assert.*'
22
24
  + '|cds.persistence.*'
23
25
  + '|sql.append'
@@ -31,7 +33,8 @@ const criticalExtensionAnnotations = new RegExp('^@(?:'
31
33
  + '|cds.query.limit'
32
34
  + '|cds.localized'
33
35
  + '|cds.valid.*'
34
- + '|cds.search)'
36
+ + '|cds.search'
37
+ + '|Capabilities.*)'
35
38
  );
36
39
 
37
40
  function locationString(element) {
@@ -52,7 +55,7 @@ function _createMandatoryAnnotationWarning(annotationName, { element, parent })
52
55
  if (element.default || element[annotationName] === false) return
53
56
  const message = `Annotation '${annotationName}' in '${
54
57
  element.annotate || element.name || parent.extend || parent.annotate
55
- }' is not supported in extensions without default value`
58
+ }' is not supported in extensions`
56
59
  return new LinterMessage(locationString(element) + message, element)
57
60
  }
58
61
 
@@ -27,7 +27,7 @@ module.exports.legacyCheck = (env = cds.env) => {
27
27
  }
28
28
 
29
29
  module.exports.lint = (extCsn, fullCsn, env = cds.env, cloneExt = false) => {
30
- const conf = env.requires[EXT_SERVICE_NAME] || env.mtx || {}
30
+ const conf = env.requires[EXT_SERVICE_NAME] || env.requires.extensibility || env.mtx || {}
31
31
  const linter_options = {}
32
32
  let x
33
33
  for (let p of LINTER_OPTIONS) if ((x = conf[p])) {
@@ -62,13 +62,14 @@ module.exports.ERR_CDS_VALIDATION_FAILURE = 'ERR_CDS_VALIDATION_FAILURE'
62
62
  * Sparsely copies the linter-relevant config from the given env into the given target
63
63
  */
64
64
  module.exports.configCopyFrom = (env, target = {}) => {
65
- if (!env.requires?.[EXT_SERVICE_NAME]) return target
65
+ const source = env.requires?.[EXT_SERVICE_NAME] ?? env.requires?.extensibility
66
+ if (!source) return target
66
67
 
67
68
  const config = {}
68
- Object.keys(env.requires[EXT_SERVICE_NAME])
69
+ Object.keys(source)
69
70
  .filter(key => LINTER_OPTIONS.includes(key)) // only let some keys pass, to not compromise security
70
- .filter(key => !!env.requires[EXT_SERVICE_NAME][key])
71
- .forEach(key => (config[key] = env.requires[EXT_SERVICE_NAME][key]))
71
+ .filter(key => !!source[key])
72
+ .forEach(key => (config[key] = source[key]))
72
73
 
73
74
  target.requires = target.requires || {}
74
75
  target.requires[EXT_SERVICE_NAME] = config // overwrite ext.service key, though
@@ -69,14 +69,3 @@ extend service cds.xt.ExtensibilityService with @private {
69
69
  );
70
70
 
71
71
  }
72
-
73
- // Access to legacy content
74
- extend service cds.xt.ExtensibilityService {
75
-
76
- @requires: ['cds.ExtensionDeveloper']
77
- @private action getMigratedProjects(
78
- tagRule: String, // optional
79
- defaultTag: String, // optional
80
- tenant: String // optional
81
- ) returns LargeBinary;
82
- }