@sap/cds-dk 10.0.7 → 10.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (341) hide show
  1. package/CHANGELOG.md +106 -0
  2. package/bin/add.js +7 -23
  3. package/bin/bind.js +14 -0
  4. package/bin/build.js +21 -34
  5. package/bin/cds.js +1 -1
  6. package/bin/compile/index.js +16 -41
  7. package/bin/completion/completionFs.js +11 -8
  8. package/bin/completion/index.js +603 -80
  9. package/bin/completion/scripts/cds.fish +620 -0
  10. package/bin/completion/scripts/cds.ps1 +403 -0
  11. package/bin/completion/scripts/cds.sh +327 -0
  12. package/bin/completion/scripts/cds.zsh +296 -0
  13. package/bin/completion/templates/cds-tmpl.fish +65 -0
  14. package/bin/completion/templates/cds-tmpl.ps1 +217 -0
  15. package/bin/completion/templates/cds-tmpl.sh +93 -0
  16. package/bin/completion/templates/cds-tmpl.zsh +74 -0
  17. package/bin/deploy/index.js +11 -1
  18. package/bin/deploy/options.js +25 -0
  19. package/{lib → bin}/deploy/to-hana/hana.js +8 -8
  20. package/{lib → bin}/deploy/to-hana/hdiDeployUtil.js +1 -1
  21. package/bin/deploy/{to-hana.js → to-hana/index.js} +1 -1
  22. package/{lib → bin}/deploy/to-hana/mtaUtil.js +1 -1
  23. package/bin/deploy/to-sql.js +0 -2
  24. package/bin/env.js +4 -1
  25. package/bin/export.js +44 -6
  26. package/bin/help/export.md +3 -0
  27. package/bin/help.js +1 -5
  28. package/bin/import.js +9 -0
  29. package/bin/init.js +6 -24
  30. package/bin/inspect.js +8 -0
  31. package/bin/lint.js +5 -3
  32. package/bin/login.js +26 -20
  33. package/bin/minify.js +6 -1
  34. package/bin/pull.js +19 -6
  35. package/bin/push.js +19 -6
  36. package/bin/repl.js +11 -2
  37. package/bin/run.js +12 -1
  38. package/bin/serve.js +13 -2
  39. package/bin/up.js +17 -11
  40. package/{lib → bin}/upgrade/constants.js +1 -1
  41. package/bin/{upgrade.js → upgrade/index.js} +2 -2
  42. package/{lib → bin}/upgrade/preflight/consistency.js +1 -1
  43. package/{lib → bin}/upgrade/preflight/index.js +1 -1
  44. package/{lib → bin}/upgrade/steps/analyze/index.js +1 -1
  45. package/{lib → bin}/upgrade/steps/install.js +1 -1
  46. package/{lib → bin}/upgrade/steps/openrewrite.js +1 -1
  47. package/{lib → bin}/upgrade/steps/removals.js +1 -1
  48. package/{lib → bin}/upgrade/steps/rewrite.js +1 -1
  49. package/{lib → bin}/upgrade/steps/verify.js +1 -1
  50. package/{lib/upgrade/index.js → bin/upgrade/upgrade.js} +2 -2
  51. package/{lib → bin}/upgrade/util/pom.js +2 -2
  52. package/{lib → bin}/upgrade/util/prompt.js +1 -1
  53. package/bin/util/containerize.js +10 -4
  54. package/bin/version.js +10 -1
  55. package/{lib → bin}/watch/hot-reload.js +1 -1
  56. package/bin/{watch.js → watch/index.js} +24 -9
  57. package/{lib → bin}/watch/livereload-connect.js +1 -1
  58. package/{lib → bin}/watch/vite-watch.js +1 -1
  59. package/{lib → bin}/watch/watched.js +2 -2
  60. package/lib/build/constants.js +1 -1
  61. package/lib/build/plugins/fiori/index.js +31 -2
  62. package/lib/build/plugins/internal.js +4 -2
  63. package/lib/build/plugins/mtx-sidecar/index.js +7 -8
  64. package/lib/build/plugins/nodejs/index.js +64 -7
  65. package/lib/build/util.js +2 -4
  66. package/lib/compile/to_asyncapi.js +1 -1
  67. package/lib/env/schema.js +16 -0
  68. package/lib/env/schemas/cds-rc.js +1 -76
  69. package/lib/import/importapi.js +2 -3
  70. package/lib/import/message.js +0 -2
  71. package/lib/init/constants.js +2 -1
  72. package/lib/init/index.js +2 -2
  73. package/lib/init/merge.js +123 -280
  74. package/lib/init/plugin.js +3 -1
  75. package/lib/init/projectReader.js +22 -6
  76. package/lib/init/registries/xs-app.js +3 -5
  77. package/lib/init/template/ai/files/mta.yaml.hbs +1 -1
  78. package/lib/init/template/ai/index.js +14 -2
  79. package/lib/init/template/ams/index.js +2 -2
  80. package/lib/init/template/app-frontend/files/containerize.yaml.hbs +2 -2
  81. package/lib/init/template/app-frontend/index.js +4 -4
  82. package/lib/init/template/application-logging/index.js +2 -2
  83. package/lib/init/template/approuter/files/package.json +1 -1
  84. package/lib/init/template/approuter/index.js +8 -3
  85. package/lib/init/template/attachments/files/package.json.hbs +1 -1
  86. package/lib/init/template/attachments/index.js +2 -2
  87. package/lib/init/template/audit-logging/index.js +2 -2
  88. package/lib/init/template/cloud-logging/files/package.json.hbs +4 -4
  89. package/lib/init/template/cloud-logging/index.js +2 -2
  90. package/lib/init/template/completion/completionSetup.js +36 -39
  91. package/lib/init/template/connectivity/index.js +2 -2
  92. package/lib/init/template/data/as-csv.js +15 -5
  93. package/lib/init/template/data/as-json.js +117 -42
  94. package/lib/init/template/data/index.js +16 -2
  95. package/lib/init/template/destination/index.js +2 -2
  96. package/lib/init/template/dynatrace/files/package.json.hbs +3 -3
  97. package/lib/init/template/dynatrace/index.js +2 -2
  98. package/lib/init/template/enterprise-messaging/index.js +2 -2
  99. package/lib/init/template/enterprise-messaging-shared/index.js +2 -2
  100. package/lib/init/template/extensibility/files/mta.yaml.hbs +11 -0
  101. package/lib/init/template/extensibility/files/xs-security.json.hbs +1 -1
  102. package/lib/init/template/extensibility/index.js +3 -3
  103. package/lib/init/template/github-actions/index.js +2 -2
  104. package/lib/init/template/hana/index.js +3 -2
  105. package/lib/init/template/hana-serverless/files/db/package.json +14 -0
  106. package/lib/init/template/hana-serverless/files/identity.values.yaml.hbs +10 -0
  107. package/lib/init/template/hana-serverless/files/mta.yaml.hbs +64 -0
  108. package/lib/init/template/hana-serverless/files/package.json.hbs +35 -0
  109. package/lib/init/template/hana-serverless/files/src/.hdiconfig +139 -0
  110. package/lib/init/template/hana-serverless/files/undeploy.json +7 -0
  111. package/lib/init/template/hana-serverless/files/values.yaml.hbs +18 -0
  112. package/lib/init/template/hana-serverless/index.js +184 -0
  113. package/lib/init/template/html5-repo/files/containerize.yaml.hbs +2 -2
  114. package/lib/init/template/html5-repo/files/mta.yaml.hbs +5 -0
  115. package/lib/init/template/html5-repo/index.js +18 -14
  116. package/lib/init/template/http/index.js +123 -26
  117. package/lib/init/template/ias/index.js +2 -2
  118. package/lib/init/template/kafka/index.js +2 -2
  119. package/lib/init/template/kyma/index.js +7 -5
  120. package/lib/init/template/malware-scanner/index.js +2 -2
  121. package/lib/init/template/mta/files/mta.yaml.hbs +1 -1
  122. package/lib/init/template/multitenancy/index.js +18 -3
  123. package/lib/init/template/notifications/index.js +2 -2
  124. package/lib/init/template/portal/files/mta.yaml.hbs +4 -0
  125. package/lib/init/template/portal/index.js +13 -8
  126. package/lib/init/template/postgres/index.js +2 -2
  127. package/lib/init/template/redis/index.js +2 -2
  128. package/lib/init/template/sample/files/db/currencies.cds +2 -0
  129. package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Authors.csv +1 -1
  130. package/lib/init/template/tiny-sample/files/nodejs/db/data/CatalogService.Books.csv +2 -2
  131. package/lib/init/template/workzone-standard/index.js +5 -5
  132. package/lib/init/template/xsuaa/index.js +20 -2
  133. package/lib/lint/eslintHelp.json +1 -1
  134. package/lib/mtx/auth_manager.js +103 -37
  135. package/lib/mtx/params.js +3 -2
  136. package/lib/mtx/settings_manager.js +45 -28
  137. package/lib/mtx/tenant_action.js +0 -1
  138. package/lib/mtx/util/credentials.js +62 -0
  139. package/node_modules/@cap-js/db-service/CHANGELOG.md +17 -0
  140. package/node_modules/@cap-js/db-service/lib/common/generic-pool.js +4 -7
  141. package/node_modules/@cap-js/db-service/lib/cqn2pql.js +1 -1
  142. package/node_modules/@cap-js/db-service/lib/cqn2sql.js +15 -11
  143. package/node_modules/@cap-js/db-service/lib/cqn4sql.js +119 -19
  144. package/node_modules/@cap-js/db-service/lib/infer/index.js +27 -16
  145. package/node_modules/@cap-js/db-service/lib/recursion-guard.js +40 -0
  146. package/node_modules/@cap-js/db-service/lib/search.js +1 -1
  147. package/node_modules/@cap-js/db-service/package.json +1 -1
  148. package/node_modules/@cap-js/sqlite/CHANGELOG.md +19 -0
  149. package/node_modules/@cap-js/sqlite/lib/SQLiteService.js +110 -14
  150. package/node_modules/@cap-js/sqlite/package.json +3 -3
  151. package/node_modules/@sap/cds/CHANGELOG.md +57 -0
  152. package/node_modules/@sap/cds/app/index.js +5 -4
  153. package/node_modules/@sap/cds/eslint.config.mjs +1 -0
  154. package/node_modules/@sap/cds/lib/compile/minify.js +14 -10
  155. package/node_modules/@sap/cds/lib/env/cds-env.js +1 -1
  156. package/node_modules/@sap/cds/lib/env/cds-requires.js +22 -11
  157. package/node_modules/@sap/cds/lib/env/defaults.js +4 -1
  158. package/node_modules/@sap/cds/lib/env/schemas/cds-rc.js +5 -2
  159. package/node_modules/@sap/cds/lib/plugins.js +9 -5
  160. package/node_modules/@sap/cds/lib/req/spawn.js +1 -1
  161. package/node_modules/@sap/cds/lib/srv/srv-dispatch.js +1 -1
  162. package/node_modules/@sap/cds/lib/srv/srv-models.js +1 -1
  163. package/node_modules/@sap/cds/lib/utils/cds-utils.js +2 -1
  164. package/node_modules/@sap/cds/libx/_runtime/common/generic/assert.js +2 -3
  165. package/node_modules/@sap/cds/libx/_runtime/common/generic/auth/restrict.js +8 -1
  166. package/node_modules/@sap/cds/libx/_runtime/common/generic/crud.js +18 -8
  167. package/node_modules/@sap/cds/libx/_runtime/fiori/lean-draft.js +25 -17
  168. package/node_modules/@sap/cds/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +9 -3
  169. package/node_modules/@sap/cds/libx/_runtime/remote/Service.js +4 -19
  170. package/node_modules/@sap/cds/libx/_runtime/remote/utils/LruCache.js +42 -0
  171. package/node_modules/@sap/cds/libx/_runtime/remote/utils/client.js +14 -4
  172. package/node_modules/@sap/cds/libx/_runtime/remote/utils/cloudSdkProvider.js +2 -9
  173. package/node_modules/@sap/cds/libx/_runtime/remote/utils/destinationClient.js +150 -0
  174. package/node_modules/@sap/cds/libx/_runtime/remote/utils/error.js +13 -0
  175. package/node_modules/@sap/cds/libx/_runtime/remote/utils/fetchClient.js +26 -18
  176. package/node_modules/@sap/cds/libx/_runtime/remote/utils/query.js +34 -23
  177. package/node_modules/@sap/cds/libx/_runtime/remote/utils/token.js +82 -0
  178. package/node_modules/@sap/cds/libx/_runtime/ucl/Service.js +36 -189
  179. package/node_modules/@sap/cds/libx/common/utils/streaming.js +16 -16
  180. package/node_modules/@sap/cds/libx/http/location.js +3 -3
  181. package/node_modules/@sap/cds/libx/odata/middleware/batch.js +16 -10
  182. package/node_modules/@sap/cds/libx/odata/middleware/metadata.js +9 -6
  183. package/node_modules/@sap/cds/libx/odata/middleware/service-document.js +1 -1
  184. package/node_modules/@sap/cds/libx/odata/parse/afterburner.js +19 -3
  185. package/node_modules/@sap/cds/libx/odata/parse/cqn2odata.js +83 -86
  186. package/node_modules/@sap/cds/libx/queue/SchedulingService.js +17 -2
  187. package/node_modules/@sap/cds/libx/queue/processing.js +1 -3
  188. package/node_modules/@sap/cds/libx/rest/RestAdapter.js +3 -7
  189. package/node_modules/@sap/cds/libx/rest/middleware/delete.js +3 -3
  190. package/node_modules/@sap/cds/libx/rest/middleware/parse.js +13 -8
  191. package/node_modules/@sap/cds/libx/rest/middleware/read.js +3 -3
  192. package/node_modules/@sap/cds/libx/rest/middleware/upsert.js +2 -2
  193. package/node_modules/@sap/cds/package.json +1 -1
  194. package/node_modules/@sap/cds-compiler/CHANGELOG.md +75 -8
  195. package/node_modules/@sap/cds-compiler/bin/cdsc.js +2 -2
  196. package/node_modules/@sap/cds-compiler/doc/IncompatibleChanges_v7.md +46 -19
  197. package/node_modules/@sap/cds-compiler/lib/api/main.js +10 -7
  198. package/node_modules/@sap/cds-compiler/lib/api/options.js +8 -2
  199. package/node_modules/@sap/cds-compiler/lib/base/csnRefs.js +5 -2
  200. package/node_modules/@sap/cds-compiler/lib/base/message-registry.js +4 -0
  201. package/node_modules/@sap/cds-compiler/lib/base/optionProcessor.js +12 -0
  202. package/node_modules/@sap/cds-compiler/lib/checks/enricher.js +1 -0
  203. package/node_modules/@sap/cds-compiler/lib/compiler/assert-consistency.js +8 -7
  204. package/node_modules/@sap/cds-compiler/lib/compiler/checks.js +3 -3
  205. package/node_modules/@sap/cds-compiler/lib/compiler/define.js +301 -75
  206. package/node_modules/@sap/cds-compiler/lib/compiler/dictionaries.js +2 -0
  207. package/node_modules/@sap/cds-compiler/lib/compiler/extend.js +40 -26
  208. package/node_modules/@sap/cds-compiler/lib/compiler/populate.js +45 -60
  209. package/node_modules/@sap/cds-compiler/lib/compiler/propagator.js +16 -7
  210. package/node_modules/@sap/cds-compiler/lib/compiler/resolve.js +48 -18
  211. package/node_modules/@sap/cds-compiler/lib/compiler/shared.js +7 -6
  212. package/node_modules/@sap/cds-compiler/lib/compiler/tweak-assocs.js +62 -50
  213. package/node_modules/@sap/cds-compiler/lib/compiler/utils.js +29 -14
  214. package/node_modules/@sap/cds-compiler/lib/edm/edmAnnoPreprocessor.js +6 -5
  215. package/node_modules/@sap/cds-compiler/lib/gen/CdlGrammar.checksum +1 -1
  216. package/node_modules/@sap/cds-compiler/lib/gen/CdlParser.js +1119 -1109
  217. package/node_modules/@sap/cds-compiler/lib/gen/Dictionary.json +19 -3
  218. package/node_modules/@sap/cds-compiler/lib/json/from-csn.js +10 -16
  219. package/node_modules/@sap/cds-compiler/lib/json/to-csn.js +58 -39
  220. package/node_modules/@sap/cds-compiler/lib/main.d.ts +8 -0
  221. package/node_modules/@sap/cds-compiler/lib/main.js +1 -0
  222. package/node_modules/@sap/cds-compiler/lib/model/csnUtils.js +4 -0
  223. package/node_modules/@sap/cds-compiler/lib/parsers/AstBuildingParser.js +2 -1
  224. package/node_modules/@sap/cds-compiler/lib/parsers/XprTree.js +8 -0
  225. package/node_modules/@sap/cds-compiler/lib/render/toCdl.js +22 -1
  226. package/node_modules/@sap/cds-compiler/lib/render/toSql.js +17 -2
  227. package/node_modules/@sap/cds-compiler/lib/render/utils/common.js +6 -1
  228. package/node_modules/@sap/cds-compiler/lib/render/utils/operators.js +27 -0
  229. package/node_modules/@sap/cds-compiler/lib/render/utils/standardDatabaseFunctions.js +125 -3
  230. package/node_modules/@sap/cds-compiler/lib/tool-lib/revealInternalProperties.js +2 -1
  231. package/node_modules/@sap/cds-compiler/lib/transform/db/applyTransformations.js +15 -0
  232. package/node_modules/@sap/cds-compiler/lib/transform/db/associations.js +10 -2
  233. package/node_modules/@sap/cds-compiler/lib/transform/db/backlinks.js +22 -6
  234. package/node_modules/@sap/cds-compiler/lib/transform/db/constraints.js +62 -1
  235. package/node_modules/@sap/cds-compiler/lib/transform/db/flattening.js +4 -3
  236. package/node_modules/@sap/cds-compiler/lib/transform/effective/annotations.js +40 -0
  237. package/node_modules/@sap/cds-compiler/lib/transform/effective/flattening.js +17 -1
  238. package/node_modules/@sap/cds-compiler/lib/transform/effective/main.js +20 -0
  239. package/node_modules/@sap/cds-compiler/lib/transform/fioriTreeViews.js +12 -1
  240. package/node_modules/@sap/cds-compiler/lib/transform/forRelationalDB.js +7 -2
  241. package/node_modules/@sap/cds-compiler/lib/transform/odata/adaptAnnotationRefs.js +11 -5
  242. package/node_modules/@sap/cds-compiler/lib/transform/translateAssocsToJoins.js +48 -10
  243. package/node_modules/@sap/cds-compiler/package.json +1 -1
  244. package/node_modules/@sap/cds-mtxs/CHANGELOG.md +49 -0
  245. package/node_modules/@sap/cds-mtxs/bin/cds-mtx-migrate.js +26 -5
  246. package/node_modules/@sap/cds-mtxs/bin/cds-mtx.js +37 -16
  247. package/node_modules/@sap/cds-mtxs/lib/utils.js +23 -7
  248. package/node_modules/@sap/cds-mtxs/package.json +1 -1
  249. package/node_modules/@sap/cds-mtxs/srv/cf/abstract-provisioning-service.js +63 -8
  250. package/node_modules/@sap/cds-mtxs/srv/cf/saas-provisioning-service.js +1 -1
  251. package/node_modules/@sap/cds-mtxs/srv/cf/sms-provisioning-service.js +23 -3
  252. package/node_modules/@sap/cds-mtxs/srv/extensibility/compat/update.js +15 -0
  253. package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/annotations.js +2 -2
  254. package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/config.js +2 -0
  255. package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/index.js +2 -0
  256. package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/protected-namespace.js +45 -0
  257. package/node_modules/@sap/cds-mtxs/srv/extensibility-service.js +30 -16
  258. package/node_modules/@sap/cds-mtxs/srv/jobs-service.js +49 -10
  259. package/node_modules/@sap/cds-mtxs/srv/model-provider.js +28 -4
  260. package/node_modules/@sap/cds-mtxs/srv/plugins/common.js +19 -12
  261. package/node_modules/@sap/cds-mtxs/srv/plugins/hana/ctnr-mgr-base.js +1 -1
  262. package/node_modules/@sap/cds-mtxs/srv/plugins/hana/hdi-ctnr-mgr.js +6 -3
  263. package/node_modules/@sap/cds-mtxs/srv/plugins/hana/serverless.js +271 -0
  264. package/node_modules/@sap/cds-mtxs/srv/plugins/hana.js +7 -10
  265. package/node_modules/@sap/cds-mtxs/srv/worker/job-worker-pool.js +212 -0
  266. package/node_modules/@sap/cds-mtxs/srv/worker/job-worker.js +61 -0
  267. package/node_modules/@sap/xsenv/CHANGELOG.md +7 -0
  268. package/node_modules/@sap/xsenv/package.json +10 -7
  269. package/node_modules/body-parser/node_modules/content-type/README.md +2 -0
  270. package/node_modules/body-parser/node_modules/content-type/dist/index.d.ts +20 -0
  271. package/node_modules/body-parser/node_modules/content-type/dist/index.js +20 -14
  272. package/node_modules/body-parser/node_modules/content-type/dist/index.js.map +1 -1
  273. package/node_modules/body-parser/node_modules/content-type/package.json +1 -1
  274. package/node_modules/hdb/cfg/VERSION +1 -1
  275. package/node_modules/hdb/lib/protocol/ClientInfo.js +16 -3
  276. package/node_modules/hdb/lib/protocol/Connection.js +1 -0
  277. package/node_modules/hdb/package.json +3 -2
  278. package/node_modules/negotiator/lib/accept.js +54 -0
  279. package/node_modules/negotiator/lib/charset.js +10 -34
  280. package/node_modules/negotiator/lib/encoding.js +9 -30
  281. package/node_modules/negotiator/lib/language.js +15 -36
  282. package/node_modules/negotiator/lib/mediaType.js +16 -134
  283. package/node_modules/negotiator/node_modules/content-type/LICENSE +22 -0
  284. package/node_modules/negotiator/node_modules/content-type/README.md +71 -0
  285. package/node_modules/negotiator/node_modules/content-type/dist/index.d.ts +46 -0
  286. package/node_modules/negotiator/node_modules/content-type/dist/index.js +176 -0
  287. package/node_modules/negotiator/node_modules/content-type/dist/index.js.map +1 -0
  288. package/node_modules/negotiator/node_modules/content-type/package.json +52 -0
  289. package/node_modules/negotiator/package.json +16 -10
  290. package/node_modules/qs/.github/THREAT_MODEL.md +3 -3
  291. package/node_modules/qs/CHANGELOG.md +15 -0
  292. package/node_modules/qs/README.md +19 -1
  293. package/node_modules/qs/dist/qs.js +21 -21
  294. package/node_modules/qs/eslint.config.mjs +1 -1
  295. package/node_modules/qs/lib/parse.js +3 -4
  296. package/node_modules/qs/lib/stringify.js +23 -8
  297. package/node_modules/qs/lib/utils.js +10 -3
  298. package/node_modules/qs/package.json +4 -4
  299. package/node_modules/qs/test/parse.js +192 -3
  300. package/node_modules/qs/test/stringify.js +317 -0
  301. package/node_modules/qs/test/utils.js +12 -0
  302. package/node_modules/type-is/node_modules/content-type/README.md +2 -0
  303. package/node_modules/type-is/node_modules/content-type/dist/index.d.ts +20 -0
  304. package/node_modules/type-is/node_modules/content-type/dist/index.js +20 -14
  305. package/node_modules/type-is/node_modules/content-type/dist/index.js.map +1 -1
  306. package/node_modules/type-is/node_modules/content-type/package.json +1 -1
  307. package/node_modules/ws/lib/permessage-deflate.js +3 -1
  308. package/node_modules/ws/package.json +1 -1
  309. package/package.json +2 -2
  310. package/bin/completion/scripts/cds-bash.sh +0 -20
  311. package/bin/completion/scripts/cds-fish.fish +0 -13
  312. package/bin/completion/scripts/cds-ps.ps1 +0 -19
  313. package/bin/completion/scripts/cds-zsh.sh +0 -13
  314. package/lib/deploy/index.js +0 -25
  315. package/lib/import/asyncapi/importAsyncAPI.js +0 -33
  316. package/lib/import/asyncapi/index.js +0 -18
  317. package/lib/import/asyncapi/parserContext.js +0 -454
  318. package/lib/import/asyncapi/utils.js +0 -49
  319. package/node_modules/@sap/cds/libx/_runtime/ucl/queries.js +0 -61
  320. package/node_modules/negotiator/HISTORY.md +0 -114
  321. /package/{lib → bin}/upgrade/context.js +0 -0
  322. /package/{lib → bin}/upgrade/migrations/cds10/migrations.json +0 -0
  323. /package/{lib → bin}/upgrade/preflight/cds-version.js +0 -0
  324. /package/{lib → bin}/upgrade/preflight/project-type.js +0 -0
  325. /package/{lib → bin}/upgrade/steps/analyze/classification.js +0 -0
  326. /package/{lib → bin}/upgrade/steps/analyze/detector.js +0 -0
  327. /package/{lib → bin}/upgrade/steps/analyze/evaluator.js +0 -0
  328. /package/{lib → bin}/upgrade/steps/analyze/reporter.js +0 -0
  329. /package/{lib → bin}/upgrade/steps/analyze/setup.js +0 -0
  330. /package/{lib → bin}/upgrade/steps/analyze/utils/detection.js +0 -0
  331. /package/{lib → bin}/upgrade/steps/analyze/utils/files.js +0 -0
  332. /package/{lib → bin}/upgrade/steps/analyze/utils/grep.js +0 -0
  333. /package/{lib → bin}/upgrade/steps/analyze/utils/yaml.js +0 -0
  334. /package/{lib → bin}/upgrade/util/workspaces.js +0 -0
  335. /package/{lib → bin}/watch/esm-resolve-registration.js +0 -0
  336. /package/{lib → bin}/watch/livereload-server.js +0 -0
  337. /package/{lib → bin}/watch/node-watch.js +0 -0
  338. /package/{lib → bin}/watch/open.js +0 -0
  339. /package/{lib → bin}/watch/watcher.js +0 -0
  340. /package/node_modules/@sap/cds-mtxs/srv/worker/{pool.js → model-worker-pool.js} +0 -0
  341. /package/node_modules/@sap/cds-mtxs/srv/worker/{load.js → model-worker.js} +0 -0
package/lib/init/merge.js CHANGED
@@ -1,11 +1,9 @@
1
1
  const { EOL } = require('node:os')
2
- const { inspect } = require('node:util')
3
2
  const cds = require('../cds')
4
3
  const YAML = require('yaml')
5
4
  const { copy, read, write, exists, path: {resolve, join} } = cds.utils
6
5
  const { readYAML, writeYAML, readJSON } = require('../util/fs')
7
6
  const { detectIndent } = require('./indent')
8
- const { colors } = require('../util/term')
9
7
 
10
8
  function _mergeObject(target, source) {
11
9
  const _isObject = item => item && typeof item === 'object' && !Array.isArray(item)
@@ -113,288 +111,119 @@ async function _mergeYAML(into, from, project, semantics = {}) {
113
111
  throw new Error(`Target YAML doesn't exist`)
114
112
  }
115
113
 
116
- const entryMap = new Map, templateEntryMap = new Map
114
+ const { forceOverwrite, additions = [], overwrites = [], deletions = [], relationships = [] } = semantics
115
+ const path = keyPath => keyPath.split('.').filter(k => k)
117
116
 
118
- const { additions, overwrites, deletions, relationships } = semantics
119
- if (relationships && Array.isArray(relationships)) {
120
- semantics.additions ??= []
121
- const add = semantics.additions
122
-
123
- for (const rel of relationships) {
124
- for (const ins of (Array.isArray(rel.insert) ? rel.insert : [rel.insert])) {
125
- if (!add.includes(ins)) add.push(ins)
126
- }
127
- const base = rel.into?.[0]
128
- if (base && !add.includes(base)) add.push(base)
129
- }
130
- }
131
-
132
- for (const entry of additions ?? []) {
133
- entryMap.set(entry, undefined)
134
- templateEntryMap.set(entry, undefined)
117
+ // Seq members correspond unless a shared top-level key holds a different scalar.
118
+ // {name:x} enriches {name:x,...}; {name:x,alias:a} and {name:x,alias:b} stay distinct.
119
+ const conflict = (a, b) => Object.keys(a).some(k =>
120
+ k in b && (typeof a[k] !== 'object' || typeof b[k] !== 'object') && JSON.stringify(a[k]) !== JSON.stringify(b[k]))
121
+ const same = (a, b) => {
122
+ if (YAML.isMap(a) && YAML.isMap(b)) { const x = a.toJSON(), y = b.toJSON(); return !conflict(x, y) && !conflict(y, x) }
123
+ return JSON.stringify(a.toJSON?.() ?? a.value) === JSON.stringify(b.toJSON?.() ?? b.value)
135
124
  }
136
- for (const deletion of deletions ?? []) {
137
- entryMap.set(deletion.item, undefined)
125
+ const has = (seq, node) => YAML.isSeq(seq) && seq.items.some(x => same(x, node))
126
+
127
+ // `where` matches a node iff every constraint holds on its JSON projection.
128
+ const matches = (node, where) => {
129
+ const json = node.toJSON?.() ?? {}
130
+ const at = (o, k) => path(k).reduce((p, s) => p?.[s], o)
131
+ return Object.entries(where).every(([k, v]) =>
132
+ Array.isArray(v) ? v.every(x => at(json, k) === x) : at(json, k) === v)
138
133
  }
139
- for (const relationship of relationships ?? []) {
140
- const [entry] = relationship.into
141
- const [insertEntry] = relationship.insert
142
- const hash = JSON.stringify(insertEntry) + ' -> ' + JSON.stringify(entry)
143
- entryMap.set(hash, undefined)
144
- }
145
-
146
- let collectionStack = [target.contents]
147
-
148
- const _getProperty = (object, keyPath) => keyPath.split('.').filter(k => k).reduce((p, k) => p && p[k], object)
149
- const _getYAMLProperty = (object, keyPath) => keyPath.split('.').filter(k => k).reduce((p, k) => p && p.get(k), object)
150
134
 
151
- const _validateWhere = (node, dict, index) => {
152
- const _addToMap = entries => entries?.filter(entry => {
153
- if (typeof entry.in === 'string') return true
154
- if (typeof entry === 'string' && !entry.where) return false // no random access caching needed for pure key paths
155
- if (Array.isArray(entry)) entry = entry[0]
156
- const neededParent = dict.get(entry.in[0])?.node
157
- return collectionStack.includes(neededParent) // lookbehind in parent collection stack
158
- }).forEach(item => {
159
- if (Array.isArray(item)) item = item[0]
160
- const json = JSON.parse(String(node))
161
- const whereFulfilled = Object.entries(item.where).every(([key, value]) => {
162
- if (Array.isArray(value)) {
163
- return value.every(v => _getProperty(json, key) === v)
164
- } else {
165
- return _getProperty(json, key) === value
166
- }
167
- })
168
- if (whereFulfilled) {
169
- const [collection] = collectionStack
170
- dict.set(item, { json, node, index, collection })
171
- }
172
- })
173
- if (additions) _addToMap(additions)
174
- if (deletions) _addToMap(deletions.map(deletion => deletion.item))
175
- if (relationships) _addToMap(relationships?.map(({into: [entry]}) => entry).filter(e => e))
176
- if (overwrites) _addToMap(overwrites.map(overwrite => overwrite.item))
135
+ // Resolve a descriptor to a live node:
136
+ // 'a.b.c' -> getIn; {in,where} -> matching seq member; [entry,'rel'] -> getIn on entry.
137
+ const locate = (doc, d) => {
138
+ if (d == null) return undefined
139
+ if (typeof d === 'string') return doc.getIn(path(d))
140
+ if (Array.isArray(d)) {
141
+ const [base, keyPath] = d
142
+ const node = locate(doc, base)
143
+ return keyPath ? node?.getIn(path(keyPath)) : node
144
+ }
145
+ const seq = locate(doc, d.in)
146
+ return YAML.isSeq(seq) ? seq.items.find(n => matches(n, d.where)) : undefined
177
147
  }
178
148
 
179
- function _traverseYAMLNode(node, index, actions, templateNode) {
180
- let shifted = false
181
- if (YAML.isMap(node)) {
182
- actions.visitMap?.(node, index)
183
- const [collection] = collectionStack
184
- if (YAML.isSeq(collection)) {
185
- collectionStack.unshift(node)
186
- shifted = true
149
+ // Generic deep-merge: recurse maps, enrich matching seq members, union scalars.
150
+ // Unmatched map members are placed by the passes below. Target scalars win unless forced.
151
+ const mergeNode = (t, s) => {
152
+ if (YAML.isMap(t) && YAML.isMap(s)) {
153
+ for (const pair of s.items) {
154
+ const tv = t.get(pair.key.value, true)
155
+ if (tv === undefined) t.add(pair)
156
+ else mergeNode(tv, pair.value)
187
157
  }
188
- } else if (YAML.isPair(node) && node.value?.items) {
189
- collectionStack.unshift(node.value)
190
- } else if (YAML.isScalar(node) && semantics.forceOverwrite && templateNode && node.comment != 'cds.noOverwrite') {
191
- node.value = templateNode.value ?? templateNode.items?.[0]?.value?.value
192
- }
193
-
194
- if (node.items) {
195
- if (YAML.isSeq(node) && templateNode?.items) {
196
- actions.mergeCollection?.(node, templateNode)
197
- _traverseYAMLCollection(node, actions, templateNode)
198
- } else {
199
- _traverseYAMLCollection(node, actions, templateNode)
158
+ } else if (YAML.isSeq(t) && YAML.isSeq(s)) {
159
+ for (const item of s.items) {
160
+ const match = t.items.find(x => same(x, item))
161
+ if (match) mergeNode(match, item)
162
+ else if (YAML.isScalar(item)) t.add(item)
200
163
  }
201
- } else if(node.value?.source === '' && YAML.isSeq(templateNode?.value)) {
202
- node.value = new YAML.YAMLSeq()
203
- collectionStack.unshift(node.value)
204
- _traverseYAMLNode(node.value, index, actions, templateNode?.value)
205
- } else if (node.value?.items || node.value && semantics.forceOverwrite) {
206
- _traverseYAMLNode(node.value, index, actions, templateNode?.value)
164
+ } else if (forceOverwrite && YAML.isScalar(t) && YAML.isScalar(s) && t.comment !== 'cds.noOverwrite') {
165
+ t.value = s.value
207
166
  }
208
-
209
- if (node.value?.items || shifted) {
210
- collectionStack.shift()
167
+ }
168
+ mergeNode(target.contents, source.contents)
169
+
170
+ // Placement: add matched (and relationship-referenced) template entries not already present.
171
+ const isEntry = e => e && typeof e === 'object' && !Array.isArray(e) && e.in !== undefined
172
+ const insertNode = ins => Array.isArray(ins) ? (ins.length === 1 ? ins[0] : undefined) : ins
173
+ const relEntries = relationships.flatMap(r => [r.into?.[0], ...[].concat(r.insert).map(insertNode)])
174
+ for (const entry of [...additions, ...relEntries].filter(isEntry)) {
175
+ const seq = locate(target, entry.in)
176
+ if (!YAML.isSeq(seq)) continue
177
+ const clone = locate(source, entry)
178
+ if (clone && !has(seq, clone)) {
179
+ entry.at !== undefined ? seq.items.splice(entry.at, 0, clone) : seq.add(clone)
211
180
  }
212
181
  }
213
- _traverseYAMLNode.bind(this)
214
-
215
- function _traverseYAMLCollection (collection, actions, templateCollection) {
216
- if (!collection) return
217
-
218
- const keyToIndex = new Map, templateIndexToIndex = new Map
219
-
220
- // Map collection items to their semantic counterpart(s)
221
- collection.items.forEach((node, i) => {
222
- if (node.key) keyToIndex.set(node.key.value, i)
223
- const entry = [...entryMap.entries()].find(([,value]) => value?.node === node)
224
- if (entry) {
225
- const [entryKey] = entry
226
- const templateEntry = entryKey && templateEntryMap.get(entryKey)
227
- const templateIndex = templateEntry?.index
228
- if (templateIndex !== undefined) templateIndexToIndex.set(templateIndex, i)
229
- }
230
- if (!templateCollection) _traverseYAMLNode(node, i, actions)
231
- })
232
-
233
- if (!templateCollection?.items) return
234
182
 
235
- templateCollection.items?.forEach((templateNode, templateIndex) => {
236
- if (YAML.isScalar(templateNode)) {
237
- if (!collection.items.map(item => item.value).includes(templateNode.value)) {
238
- collection.add(templateNode)
239
- }
240
- } else if (YAML.isPair(templateNode)) {
241
- const i = keyToIndex.get(templateNode.key.value)
242
- const [collection] = collectionStack
243
- const targetNode = collection.items?.[i]
244
- if (targetNode) {
245
- _traverseYAMLNode(targetNode, templateIndex, actions, templateNode)
246
- } else {
247
- actions.mergePair?.(collection, templateNode)
248
- }
249
- } else if (YAML.isMap(templateNode)) {
250
- const targetNode = collection.items[templateIndexToIndex.get(templateIndex)]
251
- actions.mergeCollection?.(targetNode, templateNode)
252
- if (targetNode) {
253
- _traverseYAMLNode(targetNode, templateIndex, actions, templateNode)
254
- }
255
- }
256
- })
183
+ // Relationships: wire a value into a target seq. [entry,'k'] -> {k: value}; [entry] -> the node.
184
+ for (const { insert, into } of relationships) {
185
+ const [baseEntry, seqPath, prop] = into
186
+ const seq = locate(target, seqPath ? [baseEntry, seqPath] : baseEntry)
187
+ if (!YAML.isSeq(seq)) continue
188
+ for (const ins of Array.isArray(insert) && typeof insert[0] === 'object' ? [insert] : [].concat(insert)) {
189
+ const [srcEntry, valueKey] = Array.isArray(ins) ? ins : [ins]
190
+ const srcNode = locate(target, srcEntry)
191
+ if (!srcNode) continue
192
+ const ref = prop || valueKey
193
+ const node = ref ? target.createNode({ [ref]: (valueKey ? srcNode.get(valueKey) : srcNode.get(ref)) }) : srcNode
194
+ if (!has(seq, node)) seq.add(node)
195
+ }
257
196
  }
258
- _traverseYAMLCollection.bind(this)
259
-
260
- // 1. Register the entries in the template
261
- _traverseYAMLNode(source.contents, null, {
262
- visitMap: (node, index) => _validateWhere(node, templateEntryMap, index)
263
- })
264
197
 
265
- // 2. Register the entries in the project
266
- _traverseYAMLNode(target.contents, null, {
267
- visitMap: (node, index) => _validateWhere(node, entryMap, index)
268
- })
269
-
270
- // 3. Apply overwrites to already found entries
271
- overwrites?.forEach(({ item, withValue }) => {
272
- const keyPath = Array.isArray(item) && typeof item[0] === 'string' ? item[0] : typeof item === 'string' ? item : item[1]
273
- const inEntry = Array.isArray(item) && typeof item[0] === 'object' ? item[0] : typeof item === 'object' ? item : item[1]
274
- let node
275
- if (inEntry && entryMap.get(inEntry)) {
276
- node = entryMap.get(inEntry).node // starting from item found in nested array cache
277
- } else if (typeof inEntry === 'string') {
278
- node = collectionStack[collectionStack.length - 1] // starting from root
279
- } else {
280
- return
281
- }
198
+ // Fill the bare nodes relationships just added from their full source counterparts.
199
+ if (relationships.length) mergeNode(target.contents, source.contents)
282
200
 
283
- const keys = keyPath.split('.')
284
- for (const key of keys.slice(0, -1)) {
285
- if (!node?.get(key) && typeof inEntry === 'string') return // node doesn't exist, will be added by template
286
- node = node?.get(key) ?? node
201
+ // Overwrites: set a (possibly nested) key on a located node.
202
+ for (const { item, withValue } of overwrites) {
203
+ const [base, keyPath] = Array.isArray(item) ? item : [undefined, item]
204
+ const node = base ? locate(target, base) : target.contents
205
+ const keys = path(typeof base === 'string' ? base : keyPath)
206
+ if (node?.getIn(keys.slice(0, -1)) !== undefined || base && typeof base !== 'string') {
207
+ (node.getIn(keys.slice(0, -1)) ?? node).set(keys.at(-1), withValue)
287
208
  }
288
- const tail = keys.pop()
289
- if (!node.get(tail)) {
290
- node.add({ key: tail, value: withValue })
291
- } else {
292
- node.set(tail, withValue)
293
- }
294
- })
295
-
296
- // 4. Delete entries from the project (e.g. separate deployer module when adding mtx)
297
- deletions?.forEach(({ item, relationships, key }) => {
298
- const entry = entryMap.get(item)
299
- if (!entry) return
300
- if (key) entry.collection.deleteIn([entry.index, ...key.split('.')])
301
- else entry.collection.delete(entry.index)
302
-
303
- relationships?.forEach(relationship => {
304
- const [allWithinKeyPath, inKeyPath, into] = relationship.allWithin
305
- const parent = _getYAMLProperty(target, allWithinKeyPath)
306
- for (const child of parent.items) {
307
- const grandchild = _getYAMLProperty(child, inKeyPath)
308
- const i = grandchild?.items?.findIndex(node =>
309
- node.get(into) === _getProperty(entry.json, relationship.removeProperty)
310
- ) ?? - 1
311
- if (i > -1) grandchild.delete(i)
312
- }
313
- })
314
- })
315
-
316
- // 5. Create missing entries and pairs
317
- _traverseYAMLNode(target.contents, null, {
318
- mergePair: (collection, templateNode) => {
319
- if (YAML.isMap(collection)) {
320
- collection.add(templateNode)
321
- }
322
- },
323
- mergeCollection: (targetNode, templateNode) => {
324
- if (YAML.isSeq(templateNode)) {
325
- let [,parent] = collectionStack
326
- additions?.filter(addition => {
327
- if (typeof addition.in === 'string' || Array.isArray(addition.in) && typeof addition.in[0] === 'string') return true
328
- const base = Array.isArray(addition.in) ? addition.in[0] : addition.in
329
- const keyPath = Array.isArray(addition.in) ? addition.in[1] : ''
330
- const inEntry = entryMap.get(base)
331
- if (!inEntry) return false
332
- const depth = String(keyPath).split('.').filter(Boolean).length
333
- const expectedParent = depth > 1 ? collectionStack[depth] : parent
334
- return inEntry.node === expectedParent
335
- })
336
- .filter(addition => {
337
- const keyPath = typeof addition.in === 'string' ? addition.in : Array.isArray(addition.in) && typeof addition.in[0] === 'string' ? addition.in[0] : addition.in[1]
338
- const keys = keyPath.split('.')
339
- if (keys.length > collectionStack.length + 1) return false
340
- if (keys.length > 1) parent = collectionStack[keys.length]
341
- return _getYAMLProperty(parent, keyPath) === targetNode
342
- })
343
- .filter(item => !entryMap.get(item))
344
- .forEach(item => {
345
- if (!templateEntryMap.get(item)) throw 'Error: did not find entry in template for ' + inspect(item, { colors, depth:11 }) + ' in \n' + from
346
- const templateNode = templateEntryMap.get(item).node
347
- item.at !== undefined ? targetNode.items.splice(item.at, 0, templateNode) : targetNode.add(templateNode)
348
- })
349
-
350
- }
351
- },
352
- }, source.contents)
353
-
354
- // 6. Re-register the entries in the project
355
- _traverseYAMLNode(target.contents, null, {
356
- visitMap: (node, index) => _validateWhere(node, entryMap, index)
357
- })
209
+ }
358
210
 
359
- // 7. Create missing relationships
360
- _traverseYAMLNode(target.contents, null, {
361
- mergeCollection: (targetNode, templateNode) => {
362
- if (!YAML.isSeq(templateNode)) return
363
- const targetJSON = YAML.parse(String(targetNode))
364
- for (const { insert, into } of semantics.relationships ?? []) {
365
- const [first, ...rest] = into
366
- const seqPath = rest.find(x => typeof x === 'string') || ''
367
- const keyPath = rest.length > 1 ? rest.at(-1) : null
368
- const base = entryMap.get(first)
369
- if (!base) continue
370
- const seqNode = seqPath ? _getYAMLProperty(base.node, seqPath) : base.node
371
- if (seqNode !== targetNode) continue
372
- const inserts = Array.isArray(insert) ? insert : [insert]
373
- for (const ins of inserts) {
374
- const insEntry = entryMap.get(ins)
375
- if (!insEntry) continue
376
- const srcNode = insEntry.node, srcJson = insEntry.json
377
- let key = keyPath
378
- if (!key && srcNode.get && srcNode.get('name')) key = 'name'
379
- let cand, duplicate
380
- if (key) {
381
- const val = _getProperty(srcJson, key)
382
- cand = templateNode.items.find(i => YAML.isMap(i) && i.get(key) === val) || { [key]: val }
383
- duplicate = targetJSON.some(t => t?.[key] === val)
384
- } else {
385
- cand = templateNode.items.find(i => JSON.stringify(YAML.parse(String(i))) === JSON.stringify(YAML.parse(String(srcNode)))) || srcNode
386
- const srcObj = YAML.parse(String(cand))
387
- duplicate = targetJSON.some(t => JSON.stringify(t) === JSON.stringify(srcObj))
388
- }
389
- if (!duplicate) {
390
- const clone = YAML.parse(YAML.stringify(cand))
391
- targetNode.add(clone)
392
- targetJSON.push(clone)
393
- }
394
- }
211
+ // Deletions: remove the matched node (or a sub-key), then cascade-remove references to it.
212
+ for (const { item, key, relationships: refs } of deletions) {
213
+ const seq = locate(target, item.in)
214
+ const node = locate(target, item)
215
+ if (!YAML.isSeq(seq) || !node) continue
216
+ const removed = node.toJSON()
217
+ key ? node.deleteIn(path(key)) : seq.delete(seq.items.indexOf(node))
218
+ for (const { removeProperty, allWithin } of refs ?? []) {
219
+ const [parentPath, childPath, prop] = allWithin
220
+ for (const parent of locate(target, parentPath)?.items ?? []) {
221
+ const list = parent.getIn(path(childPath))
222
+ const i = list?.items?.findIndex(n => n.get?.(prop) === removed[removeProperty]) ?? -1
223
+ if (i > -1) list.delete(i)
395
224
  }
396
225
  }
397
- }, source.contents)
226
+ }
398
227
 
399
228
  typeof into === 'string' && await writeYAML(into, target)
400
229
  return target
@@ -471,39 +300,53 @@ module.exports.merge = (...src) => {
471
300
  }
472
301
 
473
302
 
303
+ /**
304
+ * A location in a document. One of:
305
+ * - a dotted key path from the root, e.g. `'modules'` or `'a.b.c'`;
306
+ * - a {@link MatchedNode}, i.e. the member of a collection satisfying a `where` predicate;
307
+ * - a based path `[base, keyPath?]` resolving `keyPath` relative to the node `base` denotes
308
+ * (with `keyPath` omitted, the pair denotes `base` itself).
309
+ * @typedef {string | MatchedNode | [Descriptor, string?]} Descriptor
310
+ */
311
+
474
312
  /**
475
313
  * @typedef {Object} MatchedNode
476
- * @property {string | MatchedNode} in - key path or matched node to start search from
477
- * @property {Object} where - list of constraints
314
+ * @property {Descriptor} in - the collection to search
315
+ * @property {Object.<string, (string | number | boolean | Array)>} where - constraints on the
316
+ * node's JSON projection; an array value requires each of its entries to be present
317
+ * @property {number} [at] - insertion index for additions (appended when omitted)
478
318
  */
479
319
 
480
320
  /**
481
321
  * @typedef {Object} Overwrites
482
- * @property {(string | MatchedNode)[]} item - path to item to be overwritten
483
- * @property {string} withValue - replacement string
322
+ * @property {Descriptor} item - location of the value to overwrite
323
+ * @property {string | number | boolean} withValue - replacement value
484
324
  */
485
325
 
486
326
  /**
487
327
  * @typedef {Object} Deletion
488
328
  * @property {MatchedNode} item - matched node to delete
489
- * @property {MatchedNode} [key] - key path to property to delete in node (optional)
490
- * @property {Object[]} [relationships] - list of relationships to delete
491
- * @property {string} relationships[].removeProperty - key path to to-be-removed property
492
- * @property {string[]} relationships[].allWithin - key path to relationship
329
+ * @property {string} [key] - dotted key path of a sub-property to delete instead of the whole node
330
+ * @property {Object[]} [relationships] - references to cascade-remove after deletion
331
+ * @property {string} relationships[].removeProperty - property of the removed node to match on
332
+ * @property {string[]} relationships[].allWithin - `[parentPath, childPath, prop]` naming the
333
+ * sibling collections and the referencing property to strip
493
334
  */
494
335
 
495
336
  /**
496
337
  * @typedef {Object} Relationship
497
- * @property {(string | MatchedNode)[]} insert - source path to matched node
498
- * @property {(string | MatchedNode)[]} into - target path for inserted relationship
338
+ * @property {Descriptor | Descriptor[] | [Descriptor, string]} insert - source node(s), or a
339
+ * `[entry, key]` pair whose `key` value is wired in
340
+ * @property {[Descriptor, string?, string?]} into - `[baseEntry, seqPath?, prop?]` naming the
341
+ * target sequence and, optionally, the property key the wired value is written under
499
342
  */
500
343
 
501
344
  /**
502
345
  * @typedef {Object} MergingSemantics
503
- * @property {boolean} [forceOverwrite] - overwrite values for existing keys
504
- * @property {MatchedNode[]} [additions] - matched nodes to be added from source template
505
- * @property {Overwrites[]} [overwrites] - matched keys to be overwritten with given string
506
- * @property {Deletion[]} [deletions] - matched nodes to be deleted
507
- * @property {Relationship[]} [relationships] - relationships to be inserted
346
+ * @property {boolean} [forceOverwrite] - overwrite existing scalar values from the template
347
+ * @property {MatchedNode[]} [additions] - matched nodes to add from the source template
348
+ * @property {Overwrites[]} [overwrites] - values to overwrite at the given locations
349
+ * @property {Deletion[]} [deletions] - matched nodes (or sub-keys) to delete
350
+ * @property {Relationship[]} [relationships] - relationships to wire into target sequences
508
351
  */
509
352
 
@@ -45,8 +45,10 @@ module.exports = class Plugin {
45
45
 
46
46
  /**
47
47
  * Runs the combine operations for interoperability with other plugins.
48
+ * @param {string} [facet] This plugin's facet name, forwarded to `readProject(facet)`
49
+ * so `add<Facet>` accessors can tell whether this facet is the one being added.
48
50
  */
49
- async combine() { }
51
+ async combine(facet) { } // eslint-disable-line no-unused-vars
50
52
 
51
53
 
52
54
  /* ––––––––––––
@@ -65,9 +65,12 @@ module.exports = new class ProjectReader {
65
65
  * Reads the project configuration and constructs a project object.
66
66
  * This function dynamically resolves project properties and returns an object with these properties.
67
67
  *
68
+ * @param {string} [caller] The facet whose `combine()`/`run()` is requesting the project.
69
+ * Used to resolve `add<Facet>` accessors: a template asks "am I being added right now?".
70
+ * Omit when no facet context applies; `add<Facet>` then reflects only the CLI add list.
68
71
  * @returns {ProjectConfig} An object representing the project configuration.
69
72
  */
70
- readProject() {
73
+ readProject(caller) {
71
74
  if (!this.appName) this.#setPackageInfo()
72
75
  const env = this.env4('production')
73
76
  if (this.isJava) env.build.target = '.'
@@ -83,8 +86,17 @@ module.exports = new class ProjectReader {
83
86
  const _uiModule = () => !_uiEmbedded() && isdir(env.folders.app) && fs.readdirSync(resolve(cds.root, env.folders.app)).length > 0
84
87
  const _isJava = () => this.isJava
85
88
  const _extends = () => pkgJson().extends
89
+ const UI_PACKAGES = ['@ui5/cli', 'react', 'vue', 'svelte', '@angular/core', 'vite']
86
90
  const isApp = name => {
87
- return name !== 'appconfig' && !name.match(/^[._]/) && name !== 'router' && name !== 'portal' && name !== 'workzone' && name !== 'html5-deployer'
91
+ if (name.match(/^[._]/)) return false
92
+ const dir = path.join(cds.root, cds.env.folders.app, name)
93
+ if (exists(path.join(dir, 'webapp/manifest.json'))) return true
94
+ if (exists(path.join(dir, 'index.html'))) return true
95
+ const pJsonPath = path.join(dir, 'package.json')
96
+ if (!exists(pJsonPath)) return false
97
+ const { dependencies, devDependencies } = JSON.parse(fs.readFileSync(pJsonPath))
98
+ const deps = { ...dependencies, ...devDependencies }
99
+ return UI_PACKAGES.some(p => p in deps)
88
100
  }
89
101
  const reserved = {
90
102
  dependencies: () => pkgJson().dependencies,
@@ -129,6 +141,9 @@ module.exports = new class ProjectReader {
129
141
  const inbounds = manifest?.['sap.app']?.crossNavigation?.inbounds
130
142
  const [firstInbound] = Object.values(inbounds ?? { intent: { semanticObject: 'Books', action: 'display' } })
131
143
  const vizId = firstInbound.semanticObject + '-' + firstInbound.action
144
+ const appPkgPath = path.resolve(cds.root, cds.env.folders.app, app, 'package.json')
145
+ const appPkg = exists(appPkgPath) ? JSON.parse(fs.readFileSync(appPkgPath, 'utf-8')) : {}
146
+ const isStatic = !appPkg.scripts?.build
132
147
  // Try to read archiveName from ui5.yaml if it exists
133
148
  let archiveName = ''
134
149
  const ui5YamlPaths = [
@@ -145,7 +160,7 @@ module.exports = new class ProjectReader {
145
160
  }
146
161
  }
147
162
  }
148
- return { app, strippedApp: app.replace(/-/g, ''), vizId, isNotLast: i < apps.length - 1, manifestAppId: manifest?.['sap.app']?.id ?? app, archiveName }
163
+ return { app, strippedApp: app.replace(/-/g, ''), vizId, isNotLast: i < apps.length - 1, manifestAppId: manifest?.['sap.app']?.id ?? app, archiveName, isStatic }
149
164
  })
150
165
  },
151
166
  appUIPaths: () => {
@@ -159,7 +174,8 @@ module.exports = new class ProjectReader {
159
174
  appPath: () => env.folders.app,
160
175
  appVersion: () => appVersion,
161
176
  jdkVersion: () => jdkVersion,
162
- approuterPath: () => (_uiEmbedded() ? join(env.folders.app) : exists('.deploy/app-router') ? join('.deploy', 'app-router') : join(env.folders.app, 'router')).replace(/\\/g, '/'),
177
+ approuterPath: () => (_uiEmbedded() ? join(env.folders.app) : exists(join(env.folders.app, 'router')) ? join(env.folders.app, 'router') : join('.deploy', 'app-router')).replace(/\\/g, '/'),
178
+ html5DeployerPath: () => (exists(join(env.folders.app, 'html5-deployer')) ? join(env.folders.app, 'html5-deployer') : join('.deploy', 'html5-deployer')).replace(/\\/g, '/'),
163
179
  appName: () => appName,
164
180
  cleanedAppName: () => appName.replaceAll('_', '-'),
165
181
  strippedAppName: () => appName.replace(/-/g, ''),
@@ -221,8 +237,7 @@ module.exports = new class ProjectReader {
221
237
  const inProd = _inProd(facet)
222
238
  if (prefix === 'add') {
223
239
  const adding = plugin => cds.cli.command === 'add' && cds.cli.argv[0]?.split(',').includes(plugin) || cds.cli.options.add?.has(plugin)
224
- const caller = new Error().stack.split('\n')[3].replace(/\\/g, '/').match(/lib\/init\/template\/([^/]+)\/index\.js/)[1]
225
- return inProd && (adding(facet) || adding(caller))
240
+ return inProd && (adding(facet) || (caller && adding(caller)))
226
241
  }
227
242
  return inProd
228
243
  }
@@ -304,6 +319,7 @@ function _normalizeSpringBootCfg(obj) {
304
319
  * @property {string} configFile The name of the configuration file. This is typically the `package.json` for Node.js and `.cdsrc.json` for Java.
305
320
  * @property {string} appPath The path to the app folder.
306
321
  * @property {string} approuterPath The path to the approuter folder.
322
+ * @property {string} html5DeployerPath The path to the HTML5 application content deployer folder.
307
323
  * @property {boolean} hasUIEmbedded Indicates if the project uses an embedded UI.
308
324
  * @property {boolean} hasUIModule Indicates if the project is using a modular UI.
309
325
  * @property {boolean} hasUI Indicates if the project has a UI.
@@ -1,8 +1,6 @@
1
-
2
-
3
- const odataApi = {
1
+ const srvApi = {
4
2
  in: 'routes',
5
- where: { target: '/odata/$1' }
3
+ where: { destination: 'srv-api' }
6
4
  }
7
5
 
8
6
  const html5RepoApi = {
@@ -11,6 +9,6 @@ const html5RepoApi = {
11
9
  }
12
10
 
13
11
  module.exports = {
14
- odataApi,
12
+ srvApi,
15
13
  html5RepoApi
16
14
  }
@@ -11,4 +11,4 @@ resources:
11
11
  type: org.cloudfoundry.managed-service
12
12
  parameters:
13
13
  service: aicore
14
- service-plan: standard
14
+ service-plan: {{#servicePlan}}{{servicePlan}}{{/servicePlan}}{{^servicePlan}}standard{{/servicePlan}}
@@ -1,3 +1,4 @@
1
+ const cds = require('../../../cds')
1
2
  const { readProject } = require('../../projectReader')
2
3
  const { merge } = require('../../merge')
3
4
  const { srv4, aicore } = require('../../registries/mta')
@@ -9,6 +10,15 @@ module.exports = class AiTemplate extends require('../../plugin') {
9
10
  return 'SAP BTP AI Core'
10
11
  }
11
12
 
13
+ options() {
14
+ return {
15
+ 'plan': {
16
+ type: 'string',
17
+ help: 'Specify the service plan.',
18
+ }
19
+ }
20
+ }
21
+
12
22
  static hasInProduction(env) {
13
23
  const { dependencies, isJava } = readProject()
14
24
  return dependencies?.['@cap-js/ai'] || isJava && env.requires?.AICore
@@ -20,11 +30,13 @@ module.exports = class AiTemplate extends require('../../plugin') {
20
30
  await merge(__dirname, 'files/package.json.hbs').into(configFile, { project })
21
31
  }
22
32
 
23
- async combine() {
24
- const project = readProject()
33
+ async combine(facet) {
34
+ const project = readProject(facet)
25
35
  const { addMta, addKyma, addMultitenancy, srv } = project
36
+ const { plan } = cds.cli.options
26
37
 
27
38
  if (addMta) {
39
+ if (plan) project.servicePlan = plan
28
40
  const srvModule = srv4(srv.path)
29
41
  await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', {
30
42
  with: project,
@@ -26,8 +26,8 @@ module.exports = class AmsTemplate extends require('../../plugin') {
26
26
  if (project.isJava) await mvn.add('ams')
27
27
  }
28
28
 
29
- async combine() {
30
- const project = readProject()
29
+ async combine(facet) {
30
+ const project = readProject(facet)
31
31
  const { addMta, addCfManifest, addKyma } = project
32
32
 
33
33
  if (addMta) {