@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
@@ -101,13 +101,21 @@ module.exports = class HttpTemplate extends require('../../plugin') {
101
101
  const autoexposed = c['@cds.autoexposed'] || c['@cds.autoexpose']
102
102
  const valuelist = c['@cds.odata.valuelist'] === true
103
103
  if (!exposed.size && autoexposed && !valuelist) continue
104
+ const singleton = c['@odata.singleton'] || Object.keys(c).some(k => k.startsWith('@odata.singleton.')) // object form flattens to @odata.singleton.<sub>
104
105
  entities.push({
105
106
  name: c.name,
106
- readOnly: (c["@readonly"] || autoexposed || c['@odata.singleton']) ?? false,
107
+ readOnly: (c["@readonly"] || autoexposed || singleton) ?? false,
108
+ insertOnly: c['@insertonly'] ?? false,
109
+ noInsert: c['@Capabilities.InsertRestrictions.Insertable'] === false,
110
+ noUpdate: c['@Capabilities.UpdateRestrictions.Updatable'] === false,
111
+ noDelete: c['@Capabilities.DeleteRestrictions.Deletable'] === false,
107
112
  isDraft: c['@odata.draft.enabled'] ?? false,
108
- keys: c.keys
113
+ keys: c.keys,
114
+ params: c.params,
115
+ boundOps: c.actions,
116
+ elements: c.elements
109
117
  })
110
- } else if (c.kind === 'action') {
118
+ } else if (c.kind === 'action' || c.kind === 'function') {
111
119
  actions.push(c)
112
120
  }
113
121
  }
@@ -163,47 +171,77 @@ module.exports = class HttpTemplate extends require('../../plugin') {
163
171
  const headerAuth = username ? `Authorization: Basic {{username}}:{{password}}` : ''
164
172
  const headers = headerAuth ? `Content-Type: application/json\n${headerAuth}` : `Content-Type: application/json`
165
173
 
166
- service.urlPaths.forEach((urlPath) => {
174
+ const usedNames = new Set()
175
+ const uniqueName = base => {
176
+ let name = base, i = 2
177
+ while (usedNames.has(name)) name = `${base}_${i++}`
178
+ usedNames.add(name)
179
+ return name
180
+ }
181
+
182
+ service.urlPaths.forEach((rawUrlPath) => {
183
+ const urlPath = rawUrlPath.replace(/^\//, '') // avoid a double slash when the service path is '/'
167
184
  if (service.urlPaths.length > 1) {
168
185
  requests.push(`\n# Service endpoint: ${urlPath}`)
169
186
  }
170
187
 
171
188
  service.entities.forEach((e) => {
172
189
  const entityNameSimple = e.name.slice(serviceName.length + 1)
173
- const nameSlug = slug(entityNameSimple)
174
- const url = `{{server}}/${urlPath}${entityNameSimple}`
190
+ const entitySet = entityNameSimple.replace(/\./g, '_') // OData flattens nested names, e.g. E.addr -> E_addr
191
+ const nameSlug = uniqueName(slug(entitySet))
175
192
  const requestTitle = `\n### ${entityNameSimple}`
176
- requests.push(`${requestTitle}\n# @name ${nameSlug}_GET\nGET ${url}\n${headerAuth}\n`)
193
+
194
+ // parameterized entities are addressed as E(p=…)/Set and are read-only
195
+ if (e.params && Object.keys(e.params).length) {
196
+ const args = Object.entries(e.params).map(([n, p]) => `${n}=${sampleParam(p)}`).join(',')
197
+ const url = `{{server}}/${urlPath}${entitySet}(${args})/Set`
198
+ requests.push(`${requestTitle}\n# @name ${nameSlug}_GET\nGET ${url}\n${headerAuth}\n`)
199
+ return
200
+ }
201
+
202
+ const url = `{{server}}/${urlPath}${entitySet}`
203
+ if (!e.insertOnly) requests.push(`${requestTitle}\n# @name ${nameSlug}_GET\nGET ${url}\n${headerAuth}\n`) // insert-only entities cannot be read
177
204
  if (e.readOnly) return
178
205
 
179
206
  const entityData = payload[`${e.name}`] ? payload[`${e.name}`][0] : null
180
207
  if (!entityData) return
181
208
 
209
+ stripNonWritable(entityData, e.keys, e.elements)
210
+
182
211
  if (e.isDraft) {
183
- const key = Object.keys(e.keys)[0] // draft keys are always single
184
- delete entityData[key] // draft keys should always by auto generated (either UUID or through custom logic), so remove them from the payload
212
+ const keyNames = Object.keys(e.keys)
213
+ const activeId = keyPredicate(e.keys, entityData, true)
214
+ keyNames.forEach(k => delete entityData[k]) // draft keys are auto-generated, so drop them from the payload
185
215
  const postBody = JSON.stringify(entityData, null, 2)
186
- generateDraftRequests(requests, requestTitle, url, headers, headerAuth, postBody, key, service)
216
+ generateDraftRequests(requests, requestTitle, url, headers, headerAuth, postBody, keyNames, service)
217
+ if (activeId) {
218
+ const instance = `${url}${activeId.replace(/\)$/, ',IsActiveEntity=true)')}`
219
+ generateBoundOps(requests, requestTitle, instance, headers, headerAuth, nameSlug, e.boundOps, serviceName)
220
+ }
187
221
  }
188
222
  else {
189
223
  const postBody = JSON.stringify(entityData, null, 2)
190
- let id
191
- const compositeKey = Object.keys(e.keys||{}).length > 1
192
- if (compositeKey) {
193
- id = [...e.keys].map(k => k.type === 'cds.String' ? `${k.name}='${entityData[k.name]}'` : `${k.name}=${entityData[k.name]}`).join(',')
194
- } else {
195
- id = entityData[Object.keys(e.keys||{})[0]]
224
+ if (!e.noInsert) requests.push(`${requestTitle}\n# @name ${nameSlug}_POST\nPOST ${url}\n${headers}\n\n${postBody}\n`)
225
+ const id = e.insertOnly ? undefined : keyPredicate(e.keys, entityData)
226
+ if (id) {
227
+ if (!e.noUpdate) requests.push(`${requestTitle}\n# @name ${nameSlug}_PATCH\nPATCH ${url}${id}\n${headers}\n\n${postBody}\n`)
228
+ if (!e.noDelete) requests.push(`${requestTitle}\n# @name ${nameSlug}_DELETE\nDELETE ${url}${id}\n${headers}\n`)
229
+ const parenId = keyPredicate(e.keys, entityData, true)
230
+ generateBoundOps(requests, requestTitle, `${url}${parenId}`, headers, headerAuth, nameSlug, e.boundOps, serviceName)
196
231
  }
197
- compositeKey ? id = `(${id})` : id = `/${id}`
198
- requests.push(`${requestTitle}\n# @name ${nameSlug}_POST\nPOST ${url}\n${headers}\n\n${postBody}\n`)
199
- requests.push(`${requestTitle}\n# @name ${nameSlug}_PATCH\nPATCH ${url}${id}\n${headers}\n\n${postBody}\n`)
200
- requests.push(`${requestTitle}\n# @name ${nameSlug}_DELETE\nDELETE ${url}${id}\n${headers}\n`)
201
232
  }
202
233
  })
203
234
 
204
235
  service.actions.forEach((a) => {
205
236
  const simpleNameAction = a.name.slice(serviceName.length + 1)
206
237
  const url = `{{server}}/${urlPath}${simpleNameAction}`
238
+ const actionSlug = uniqueName(slug(simpleNameAction))
239
+
240
+ if (a.kind === 'function') {
241
+ const args = Object.entries(a.params || {}).map(([n, p]) => `${n}=${literal(p.type, payload[a.name]?.[0]?.[n])}`).join(',')
242
+ requests.push(`\n### ${simpleNameAction}\n# @name ${actionSlug}_GET\nGET ${url}(${args})\n${headerAuth}\n`)
243
+ return
244
+ }
207
245
 
208
246
  let actionPayload = {}
209
247
  if (a.params) {
@@ -211,26 +249,85 @@ module.exports = class HttpTemplate extends require('../../plugin') {
211
249
  actionPayload[pName] = payload[a.name]?.[0]?.[pName] ?? null
212
250
  }
213
251
  }
214
- requests.push(`\n### ${simpleNameAction}\n# @name ${simpleNameAction}_POST\nPOST ${url}\n${headers}\n\n${JSON.stringify(actionPayload, null, 2)}\n`)
252
+ requests.push(`\n### ${simpleNameAction}\n# @name ${actionSlug}_POST\nPOST ${url}\n${headers}\n\n${JSON.stringify(actionPayload, null, 2)}\n`)
215
253
  })
216
254
 
217
255
  })
218
256
  this.#write(requests, serviceName)
219
257
  }
220
258
 
221
- function generateDraftRequests(requests, title, url, headers, headerAuth, postBody, key, service) {
259
+ function generateDraftRequests(requests, title, url, headers, headerAuth, postBody, keys, service) {
222
260
  const nameDraftsCreate = slug(title+'_Draft_POST')
261
+ const draftVar = k => keys.length > 1 ? `draftID_${k}` : 'draftID'
262
+ const predicate = keys.map(k => `${k}={{${draftVar(k)}}}`).join(',') + ',IsActiveEntity=false'
263
+ const bindings = keys.map(k => `@${draftVar(k)}={{${nameDraftsCreate}.response.body.$.${k}}}`).join('\n')
223
264
  requests.push(`${title} Drafts GET\n# @name ${slug(title+'_Drafts_GET')}\nGET ${url}?$filter=(IsActiveEntity eq false)\n${headerAuth}\n`) // unencoded URL for better readability (client can handle this)
224
265
  requests.push(`${title} Draft POST\n# @name ${nameDraftsCreate}\nPOST ${url}\n${headers}\n\n${postBody}\n`)
225
- requests.push(`\n### Result from POST request above\n@draftID={{${nameDraftsCreate}.response.body.$.${key}}}\n`)
226
- requests.push(`${title} Draft PATCH\n# @name ${slug(title+'_Draft_Patch')}\nPATCH ${url}(${key}={{draftID}},IsActiveEntity=false)\n${headers}\n\n${postBody}\n`)
227
- requests.push(`${title} Draft Prepare\n# @name ${slug(title+'_Draft_Prepare')}\nPOST ${url}(${key}={{draftID}},IsActiveEntity=false)/${service.name}.draftPrepare\n${headers}\n\n{}\n`)
228
- requests.push(`${title} Draft Activate\n# @name ${slug(title+'_Draft_Activate')}\nPOST ${url}(${key}={{draftID}},IsActiveEntity=false)/${service.name}.draftActivate\n${headers}\n\n{}\n`)
266
+ requests.push(`\n### Result from POST request above\n${bindings}\n`)
267
+ requests.push(`${title} Draft PATCH\n# @name ${slug(title+'_Draft_Patch')}\nPATCH ${url}(${predicate})\n${headers}\n\n${postBody}\n`)
268
+ requests.push(`${title} Draft Prepare\n# @name ${slug(title+'_Draft_Prepare')}\nPOST ${url}(${predicate})/${service.name}.draftPrepare\n${headers}\n\n{}\n`)
269
+ requests.push(`${title} Draft Activate\n# @name ${slug(title+'_Draft_Activate')}\nPOST ${url}(${predicate})/${service.name}.draftActivate\n${headers}\n\n{}\n`)
229
270
  }
230
271
 
231
272
  function slug(str) {
232
273
  return str.trim().replace(/[#\\. ]/g, '')
233
274
  }
275
+
276
+ // drop non-writable fields (readonly/computed/managed) from a request body, keeping keys for addressing
277
+ function stripNonWritable(data, keys, elements) {
278
+ const keyNames = new Set(Object.keys(keys || {}))
279
+ for (const name of Object.keys(data)) {
280
+ if (keyNames.has(name)) continue
281
+ const el = elements?.[name]
282
+ if (el && (el['@readonly'] || el['@Core.Computed'] || el['@cds.on.insert'] || el['@cds.on.update'])) delete data[name]
283
+ }
284
+ }
285
+
286
+ // placeholder value for a parameterized-entity argument
287
+ function sampleParam(p) {
288
+ const t = p.type
289
+ if (t === 'cds.String' || t === 'cds.UUID' || t === 'cds.Date' || t === 'cds.DateTime' || t === 'cds.Timestamp') return `''`
290
+ if (t === 'cds.Boolean') return 'true'
291
+ return '0'
292
+ }
293
+
294
+ // OData URL literal for a value of the given type
295
+ function literal(type, value) {
296
+ if (value === undefined || value === null) return 'null'
297
+ return type === 'cds.String' ? `'${value}'` : `${value}`
298
+ }
299
+
300
+ // key predicate from scalar keys with a sample value; associations, structs, binary types and unseeded keys aren't addressable
301
+ function keyPredicate(keys, data, paren) {
302
+ const notAddressable = new Set(['cds.Association', 'cds.Composition', 'cds.Binary', 'cds.LargeBinary', 'cds.Vector'])
303
+ const scalar = [...(keys || [])].filter(k => !k.is_struct && !notAddressable.has(k.type) && data[k.name] !== undefined)
304
+ if (!scalar.length) return undefined
305
+ const val = k => literal(k.type, data[k.name])
306
+ if (paren || scalar.length > 1) return `(${scalar.map(k => `${k.name}=${val(k)}`).join(',')})`
307
+ return `/${val(scalar[0])}`
308
+ }
309
+
310
+ // sample value for a bound-operation parameter
311
+ function sampleValue(type) {
312
+ if (type === 'cds.Boolean') return true
313
+ if (type === 'cds.Integer' || type === 'cds.Int16' || type === 'cds.Int32' || type === 'cds.Int64' || type === 'cds.Decimal' || type === 'cds.Double') return 0
314
+ return ''
315
+ }
316
+
317
+ // bound actions (POST body) and functions (GET with inline args) on a single instance
318
+ function generateBoundOps(requests, title, instanceUrl, headers, headerAuth, nameSlug, boundOps, serviceName) {
319
+ for (const [name, op] of Object.entries(boundOps || {})) {
320
+ const params = op.params || {}
321
+ if (op.kind === 'function') {
322
+ const args = Object.entries(params).map(([n, p]) => `${n}=${literal(p.type, sampleValue(p.type))}`).join(',')
323
+ requests.push(`${title} ${name}\n# @name ${nameSlug}_${slug(name)}_GET\nGET ${instanceUrl}/${serviceName}.${name}(${args})\n${headerAuth}\n`)
324
+ } else {
325
+ const body = {}
326
+ for (const [n, p] of Object.entries(params)) body[n] = sampleValue(p.type)
327
+ requests.push(`${title} ${name}\n# @name ${nameSlug}_${slug(name)}_POST\nPOST ${instanceUrl}/${serviceName}.${name}\n${headers}\n\n${JSON.stringify(body, null, 2)}\n`)
328
+ }
329
+ }
330
+ }
234
331
  }
235
332
 
236
333
  async #getHostnameAndAuth(service, csn) {
@@ -22,8 +22,8 @@ module.exports = class IasTemplate extends require('../../plugin') {
22
22
  if (isNodejs) await sort('package.json', 'dependencies')
23
23
  }
24
24
 
25
- async combine() {
26
- const project = readProject()
25
+ async combine(facet) {
26
+ const project = readProject(facet)
27
27
  const { isJava, addMta, hasMta, addCfManifest, addKyma, addMultitenancy, hasApprouter, hasMultitenancy, srv } = project
28
28
 
29
29
  if (addMultitenancy) {
@@ -27,8 +27,8 @@ module.exports = class KafkaTemplate extends require('../../plugin') {
27
27
  if (isJava) await mvn.add('kafka')
28
28
  }
29
29
 
30
- async combine() {
31
- const project = readProject()
30
+ async combine(facet) {
31
+ const project = readProject(facet)
32
32
  const { addMta, srv, addKyma } = project
33
33
 
34
34
  if (addMta) {
@@ -73,13 +73,13 @@ module.exports = class KymaTemplate extends require('../../plugin') {
73
73
 
74
74
  }
75
75
 
76
- async combine() {
76
+ async combine(facet) {
77
77
  // REVISIT: This must be moved to the respective plugins
78
78
  const {
79
- addHana, addMultitenancy, addXsuaa, hasApprouter,
79
+ addHana, addHanaServerless, hasHanaServerless, addMultitenancy, addXsuaa, hasApprouter,
80
80
  addApprouter, addIas, addAms, hasXsuaa, hasMultitenancy, addWorkzoneStandard,
81
81
  addHtml5Repo, hasHtml5Repo, addAppFrontend
82
- } = readProject()
82
+ } = readProject(facet)
83
83
 
84
84
  if (addHtml5Repo || addWorkzoneStandard || addApprouter && hasHtml5Repo) {
85
85
  if (addHtml5Repo) {
@@ -106,8 +106,10 @@ module.exports = class KymaTemplate extends require('../../plugin') {
106
106
  await KymaTemplate.mergeDependency('service-instance', 'subscription-manager')
107
107
  }
108
108
  }
109
- if (addHana || addMultitenancy) {
110
- if (hasMultitenancy) {
109
+ if (addHana || addHanaServerless || addMultitenancy) {
110
+ if (hasHanaServerless) {
111
+ await KymaTemplate.mergeDependency('service-instance', 'db')
112
+ } else if (hasMultitenancy) {
111
113
  await KymaTemplate.mergeDependency('service-instance', 'service-manager')
112
114
  await KymaTemplate.mergeDependency('content-deployment', 'mtx-upgrade')
113
115
  } else {
@@ -21,8 +21,8 @@ module.exports = class MalwareScannerTemplate extends require('../../plugin') {
21
21
  }
22
22
  }
23
23
 
24
- async combine() {
25
- const project = readProject()
24
+ async combine(facet) {
25
+ const project = readProject(facet)
26
26
  const { addMta, addKyma, srv } = project
27
27
 
28
28
  if (addMta) {
@@ -11,7 +11,7 @@ build-parameters:
11
11
  - builder: custom
12
12
  commands:
13
13
  - npm ci
14
- - npx cds build --production{{#isMonorepoMicroservice}} --ws-pack{{/isMonorepoMicroservice}}
14
+ - npx cds build --production
15
15
  {{/isNodejs}}
16
16
  modules:
17
17
  - name: {{appName}}-srv
@@ -40,11 +40,11 @@ module.exports = class MultitenancyTemplate extends require('../../plugin') {
40
40
  await copyRenderedJSON(join(__dirname, 'files', 'package.sidecar.json.hbs'), join('mtx', 'sidecar/package.json'), project)
41
41
  }
42
42
 
43
- async combine() {
44
- const project = readProject()
43
+ async combine(facet) {
44
+ const project = readProject(facet)
45
45
  const {
46
46
  isNodejs, isJava, addMta, hasMta,
47
- addXsuaa, hasXsuaa, addIas, hasIas, hasHana, addKyma, hasApprouter,
47
+ addXsuaa, hasXsuaa, addIas, hasIas, hasHana, hasHanaServerless, addKyma, hasApprouter,
48
48
  srv, appName
49
49
  } = project
50
50
 
@@ -98,6 +98,21 @@ module.exports = class MultitenancyTemplate extends require('../../plugin') {
98
98
  `https://{{ .Release.Name }}-sidecar-{{ .Release.Namespace }}.{{ .Values.global.domain }}`
99
99
  }}}
100
100
  }).into('chart/values.yaml',{ forceOverwrite: true })
101
+
102
+ if (hasHanaServerless) {
103
+ await merge('chart/values.yaml').remove([
104
+ 'service-manager',
105
+ 'srv.bindings.service-manager',
106
+ 'sidecar.bindings.service-manager',
107
+ 'mtx-upgrade.bindings.service-manager'
108
+ ])
109
+ await merge({
110
+ srv: { bindings: { db: { serviceInstanceName: 'db' } } },
111
+ sidecar: { bindings: { db: { serviceInstanceName: 'db' } } },
112
+ 'mtx-upgrade': { bindings: { db: { serviceInstanceName: 'db' } } }
113
+ }).into('chart/values.yaml')
114
+ await merge('chart/Chart.yaml').remove([{ dependencies: { alias: 'service-manager' } }])
115
+ }
101
116
  }
102
117
 
103
118
  // cds10 move to if above
@@ -1,5 +1,5 @@
1
1
  const cds = require('../../../cds')
2
- const { exists, mkdirp, path } = cds.utils
2
+ const { fs: { promises: { cp } }, exists, mkdirp, path } = cds.utils
3
3
  const { OPTIONS: { NODEJS, JAVA } } = require('../../constants')
4
4
  const term = require('../../../util/term')
5
5
  const { merge } = require('../../merge')
@@ -24,10 +24,12 @@ module.exports = class NodejsTemplate extends require('../../plugin') {
24
24
 
25
25
  async run() {
26
26
  const { db, srv, app } = cds.env.folders
27
- if (cds.cli.command === 'init' && cds.cli.options.force) {
27
+ if (cds.cli.command === 'init' || cds.cli.options.force) {
28
28
  await renderAndCopy(path.join(__dirname, 'files'), cds.root, { projectName: path.basename(cds.root) })
29
29
  } else {
30
30
  await merge(__dirname, 'files/package.json.hbs').into('package.json', { with: { projectName: path.basename(cds.root) }})
31
+ await cp(path.join(__dirname, 'files/eslint.config.mjs'), 'eslint.config.mjs', { force: false })
32
+ await cp(path.join(__dirname, 'files/.vscode'), '.vscode', { recursive: true, force: false })
31
33
  }
32
34
  await Promise.all([db, srv, app].map(p => mkdirp(p)))
33
35
  }
@@ -33,8 +33,8 @@ module.exports = class NotificationsTemplate extends require('../../plugin') {
33
33
  await merge(__dirname, 'files/package.json.hbs').into(configFile, { project })
34
34
  }
35
35
 
36
- async combine() {
37
- const project = readProject()
36
+ async combine(facet) {
37
+ const project = readProject(facet)
38
38
  const { addMta } = project
39
39
 
40
40
  if (addMta) {
@@ -17,9 +17,11 @@ modules:
17
17
  requires:
18
18
  - name: {{appName}}-portal
19
19
 
20
+ {{#withApps}}
20
21
  - name: {{appName}}-app-deployer
21
22
  type: com.sap.application.content
22
23
  path: {{#isNodejs}}gen{{/isNodejs}}{{#isJava}}.{{/isJava}}
24
+ {{/withApps}}
23
25
 
24
26
  - name: {{appName}}-portal-deployer
25
27
  type: com.sap.application.content
@@ -50,9 +52,11 @@ modules:
50
52
  name: {{appName}}-portal-deployer-ias-key
51
53
  {{/hasIas}}
52
54
  - name: {{appName}}-html5-repo-host
55
+ {{#withApps}}
53
56
  - name: {{appName}}-app-deployer
54
57
  deployed-after:
55
58
  - {{appName}}-app-deployer
59
+ {{/withApps}}
56
60
 
57
61
  resources:
58
62
  - name: {{appName}}-portal
@@ -27,9 +27,9 @@ module.exports = class PortalTemplate extends require('../../plugin') {
27
27
  await renderAndCopy(path.join(__dirname, 'files/portal-site'), 'app/portal/portal-site', project)
28
28
  }
29
29
 
30
- async combine() {
31
- const project = readProject()
32
- const { isJava, addMta, hasMta, srv, addHtml5Repo, addXsuaa, addApprouter, addMultitenancy, addKyma, hasApprouter, hasHtml5Repo, hasMultitenancy, hasXsuaa } = project
30
+ async combine(facet) {
31
+ const project = readProject(facet)
32
+ const { isJava, addMta, hasMta, srv, apps, addHtml5Repo, addXsuaa, addApprouter, addMultitenancy, addKyma, hasApprouter, hasHtml5Repo, hasMultitenancy, hasXsuaa } = project
33
33
 
34
34
  if (addMultitenancy) {
35
35
  await merge(__dirname, 'files/package.sidecar.json').into('mtx/sidecar/package.json')
@@ -37,14 +37,19 @@ module.exports = class PortalTemplate extends require('../../plugin') {
37
37
 
38
38
  if (addMta || (addXsuaa || addHtml5Repo || addApprouter || addMultitenancy) && hasMta) {
39
39
  const srvModule = srv4(srv.path)
40
- const additions = [srvModule, portal, appDeployer, portalDeployer]
40
+ const hasApps = apps.length > 0
41
+ project.withApps = hasApps
42
+ const additions = [srvModule, portal, ...(hasApps ? [appDeployer] : []), portalDeployer]
41
43
  const relationships = [{
42
44
  insert: [portal, 'name'],
43
45
  into: [portalDeployer, 'requires', 'name']
44
- }, {
45
- insert: [appDeployer, 'name'],
46
- into: [portalDeployer, 'requires', 'name']
47
46
  }]
47
+ if (hasApps) {
48
+ relationships.push({
49
+ insert: [appDeployer, 'name'],
50
+ into: [portalDeployer, 'requires', 'name']
51
+ })
52
+ }
48
53
 
49
54
  if (hasXsuaa) {
50
55
  relationships.push({
@@ -81,7 +86,7 @@ module.exports = class PortalTemplate extends require('../../plugin') {
81
86
  if (addKyma) {
82
87
  await merge(__dirname, 'files/values.yaml.hbs').into('chart/values.yaml', { with: project })
83
88
  await KymaTemplate.mergeDependency('service-instance', 'portal')
84
- await renderAndCopy(path.join(__dirname, 'files/portal-site'), 'app/html5-deployer/portal/portal-site', project)
89
+ await renderAndCopy(path.join(__dirname, 'files/portal-site'), path.join(project.html5DeployerPath, 'portal/portal-site'), project)
85
90
  }
86
91
  }
87
92
  }
@@ -27,8 +27,8 @@ module.exports = class PostgresTemplate extends require('../../plugin') {
27
27
  await sort('package.json', 'dependencies')
28
28
  }
29
29
 
30
- async combine() {
31
- const project = readProject()
30
+ async combine(facet) {
31
+ const project = readProject(facet)
32
32
  const { addMta, srv, hasMultitenancy, addKyma, hasKyma, addMultitenancy } = project
33
33
 
34
34
  if (addMta) {
@@ -24,8 +24,8 @@ module.exports = class extends require('../../plugin') {
24
24
  await merge(__dirname, 'files/package.json.hbs').into('package.json')
25
25
  }
26
26
 
27
- async combine() {
28
- const project = readProject()
27
+ async combine(facet) {
28
+ const project = readProject(facet)
29
29
  const { addMta, srv } = project
30
30
 
31
31
  if (addMta) {
@@ -1,5 +1,7 @@
1
1
  using { sap } from '@sap/cds/common';
2
2
 
3
+ namespace sap.capire.bookshop;
4
+
3
5
  extend sap.common.Currencies with {
4
6
  // Currencies.code = ISO 4217 alphabetic three-letter code
5
7
  // with the first two letters being equal to ISO 3166 alphabetic country codes
@@ -1,5 +1,5 @@
1
1
  ID,name,dateOfBirth,placeOfBirth,dateOfDeath,placeOfDeath
2
2
  101,Emily Brontë,1818-07-30,"Thornton, Yorkshire",1848-12-19,"Haworth, Yorkshire"
3
3
  107,Charlotte Brontë,1818-04-21,"Thornton, Yorkshire",1855-03-31,"Haworth, Yorkshire"
4
- 150,Edgar Allen Poe,1809-01-19,"Boston, Massachusetts",1849-10-07,"Baltimore, Maryland"
4
+ 150,Edgar Allan Poe,1809-01-19,"Boston, Massachusetts",1849-10-07,"Baltimore, Maryland"
5
5
  170,Richard Carpenter,1929-08-14,"King’s Lynn, Norfolk",2012-02-26,"Hertfordshire, England"
@@ -1,6 +1,6 @@
1
1
  ID,title,author
2
2
  1,Wuthering Heights,Emily Brontë
3
3
  2,Jane Eyre,Charlotte Brontë
4
- 3,The Raven,Edgar Allen Poe
5
- 4,Eleonora,Edgar Allen Poe
4
+ 3,The Raven,Edgar Allan Poe
5
+ 4,Eleonora,Edgar Allan Poe
6
6
  5,Catweazle,Richard Carpenter
@@ -4,7 +4,7 @@ const { readProject } = require('../../projectReader')
4
4
  const { merge } = require('../../merge')
5
5
  const { join } = require('path')
6
6
  const { destination, destinations, xsuaa, srv4, html5RepoHost, mtxSidecar4 } = require('../../registries/mta')
7
- const { odataApi } = require('../../registries/xs-app')
7
+ const { srvApi } = require('../../registries/xs-app')
8
8
 
9
9
  module.exports = class extends require('../../plugin') {
10
10
 
@@ -39,8 +39,8 @@ module.exports = class extends require('../../plugin') {
39
39
  }
40
40
  }
41
41
 
42
- async combine() {
43
- const project = readProject()
42
+ async combine(facet) {
43
+ const project = readProject(facet)
44
44
  const { isJava, addMta, hasMta, srv, apps, appPath, appUIPaths, addMultitenancy, addXsuaa, strippedAppName } = project
45
45
 
46
46
  await Promise.all(appUIPaths.map(async p => {
@@ -58,9 +58,9 @@ module.exports = class extends require('../../plugin') {
58
58
  }))
59
59
 
60
60
  await Promise.all(apps.map(async ({ app }) => {
61
- const additions = [odataApi]
61
+ const additions = [srvApi]
62
62
  const overwrites = [{
63
- item: [odataApi, 'destination'],
63
+ item: [srvApi, 'destination'],
64
64
  withValue: `srv-api`
65
65
  }]
66
66
  project.app = app
@@ -32,8 +32,8 @@ module.exports = class XsuaaTemplate extends require('../../plugin') {
32
32
  await merge(__dirname, 'files/package.json.hbs').into(configFile, { project, forceOverwrite: true })
33
33
  }
34
34
 
35
- async combine() {
36
- const project = readProject()
35
+ async combine(facet) {
36
+ const project = readProject(facet)
37
37
  const { addMultitenancy, hasMultitenancy, addMta, hasMta, addKyma, isJava, srv, hasKyma } = project
38
38
 
39
39
  const cds = require('../../../../lib')
@@ -81,6 +81,16 @@ module.exports = class XsuaaTemplate extends require('../../plugin') {
81
81
  }
82
82
  }
83
83
  await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', { project, additions, overwrites, relationships })
84
+ if (project.hasExtensibility) {
85
+ const extTemplate = require('path').join(__dirname, '../extensibility')
86
+ await merge(extTemplate, 'files', 'mta.yaml.hbs').into('mta.yaml', {
87
+ project,
88
+ additions: [
89
+ xsuaa,
90
+ { in: [xsuaa, 'parameters.config.role-collections'], where: { name: `ExtensionDeveloper (${project.appName} \${org}-\${space})` } }
91
+ ]
92
+ })
93
+ }
84
94
  }
85
95
 
86
96
  if (addKyma || addMultitenancy && hasKyma) {
@@ -96,6 +106,14 @@ module.exports = class XsuaaTemplate extends require('../../plugin') {
96
106
  'role-template-references': [`$XSAPPNAME.${role.name}`],
97
107
  }))
98
108
  }
109
+ if (project.hasExtensibility) {
110
+ parameters['role-collections'] ??= []
111
+ parameters['role-collections'].push({
112
+ name: `ExtensionDeveloper (${project.appName} {{ .Release.Namespace }})`,
113
+ description: 'generated',
114
+ 'role-template-references': ['$XSAPPNAME.ExtensionDeveloper'],
115
+ })
116
+ }
99
117
  await merge({ xsuaa: { parameters } }).into('chart/values.yaml')
100
118
  await KymaTemplate.mergeDependency('service-instance', 'xsuaa')
101
119
 
@@ -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",