@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
@@ -1112,14 +1112,12 @@
1112
1112
  "Type": "Core.Tag"
1113
1113
  },
1114
1114
  "Common.WebSocketBaseURL": {
1115
- "$experimental": true,
1116
1115
  "AppliesTo": [
1117
1116
  "EntityContainer"
1118
1117
  ],
1119
1118
  "Type": "Edm.String"
1120
1119
  },
1121
1120
  "Common.WebSocketChannel": {
1122
- "$experimental": true,
1123
1121
  "AppliesTo": [
1124
1122
  "EntityContainer"
1125
1123
  ],
@@ -1795,6 +1793,13 @@
1795
1793
  ],
1796
1794
  "Type": "UI.BadgeType"
1797
1795
  },
1796
+ "UI.CardItem": {
1797
+ "$experimental": true,
1798
+ "AppliesTo": [
1799
+ "EntityType"
1800
+ ],
1801
+ "Type": "UI.CardItemType"
1802
+ },
1798
1803
  "UI.Chart": {
1799
1804
  "AppliesTo": [
1800
1805
  "EntityType"
@@ -1897,7 +1902,6 @@
1897
1902
  "Type": "Edm.Boolean"
1898
1903
  },
1899
1904
  "UI.Emphasized": {
1900
- "$experimental": true,
1901
1905
  "AppliesTo": [
1902
1906
  "Record"
1903
1907
  ],
@@ -3443,6 +3447,9 @@
3443
3447
  "Properties": {
3444
3448
  "Discretionary": "Edm.Boolean",
3445
3449
  "SourceEntities": "Collection(Edm.NavigationPropertyPath)",
3450
+ "SourceEntitiesDeleted": "Collection(Edm.NavigationPropertyPath)",
3451
+ "SourceEntitiesInserted": "Collection(Edm.NavigationPropertyPath)",
3452
+ "SourceEntitiesUpdated": "Collection(Edm.NavigationPropertyPath)",
3446
3453
  "SourceEvents": "Collection(Edm.String)",
3447
3454
  "SourceProperties": "Collection(Edm.PropertyPath)",
3448
3455
  "TargetEntities": "Collection(Edm.NavigationPropertyPath)",
@@ -4312,6 +4319,15 @@
4312
4319
  "TypeImageUrl": "Edm.String"
4313
4320
  }
4314
4321
  },
4322
+ "UI.CardItemType": {
4323
+ "$experimental": true,
4324
+ "$kind": "ComplexType",
4325
+ "Properties": {
4326
+ "Actions": "Collection(UI.DataFieldAbstract)",
4327
+ "Details": "Collection(UI.Facet)",
4328
+ "Header": "Edm.AnnotationPath"
4329
+ }
4330
+ },
4315
4331
  "UI.ChartAxisAutoScaleBehaviorType": {
4316
4332
  "$kind": "ComplexType",
4317
4333
  "Properties": {
@@ -596,6 +596,7 @@ const schema = compileSchema( {
596
596
  any: { type: asQuantifier }, // probably just CSN v0.1.0
597
597
  distinct: { type: asQuantifier },
598
598
  all: { type: asQuantifier },
599
+ one: { type: boolOrNull },
599
600
  // further query properties: -----------------------------------------------
600
601
  excluding: {
601
602
  inKind: [ '$column' ],
@@ -1661,16 +1662,11 @@ function args( exprs, spec ) {
1661
1662
 
1662
1663
  function expr( e, spec ) {
1663
1664
  if (Array.isArray( e )) {
1664
- if (e.length > 1) { // struct-xpr
1665
+ if (e.length > 1) // parse CSN produced with option 'structXpr'
1666
+ return condition( e, spec );
1667
+ if (e.length === 1) { // CSN v.0.1.0 way for parentheses
1665
1668
  const loc = location();
1666
- const xsn = exprArgs( e, spec );
1667
- return (e.length < 3) // optimization
1668
- ? { op: { val: 'ixpr', location: loc }, args: xsn, location: loc }
1669
- : xsnAsTree( e, xsn, loc );
1670
- }
1671
- else if (e.length === 1) { // CSN v.0.1.0 way for parentheses
1672
- const loc = location();
1673
- if (e[0] && !e[0].op) // do not complain with 'op' (for which we complain)
1669
+ if (e[0] && !e[0].op) // do not complain with 'op' (for which we complain)
1674
1670
  replaceZeroValue( spec, 'zero-parens' );
1675
1671
  ++virtualLine;
1676
1672
  const r = expr( e[0], spec );
@@ -1714,13 +1710,9 @@ function exprArgs( cond, spec ) {
1714
1710
  function condition( cond, spec ) {
1715
1711
  const loc = location();
1716
1712
  const xsn = exprArgs( cond, spec );
1717
- // TODO sql-like backends: with the commented `return`, test3 generated sql
1718
- // files will not have the unnecessary `(…)` around `on` anymore → extra PR
1719
- const tree = (cond.length < 3) ? xsn : xsnAsTree( cond, xsn, loc ).args;
1720
- return { op: { val: 'xpr', location: loc }, args: tree, location: loc };
1721
- // return (cond.length < 3) // optimization
1722
- // ? { op: { val: 'ixpr', location: loc }, args: xsn, location: loc }
1723
- // : xsnAsTree( cond, xsn, loc );
1713
+ return (cond.length < 3) // nothing to structurize with 1 or 2 nodes
1714
+ ? { op: { val: 'ixpr', location: loc }, args: xsn, location: loc }
1715
+ : xsnAsTree( cond, xsn, loc );
1724
1716
  }
1725
1717
 
1726
1718
  // Queries (std signature) ---------------------------------------------------
@@ -1892,6 +1884,8 @@ function calculateKind( def, spec, xsn ) {
1892
1884
  }
1893
1885
  if (spec.prop === 'extensions') {
1894
1886
  inExtensions = (def.extend) ? '' : 'annotate';
1887
+ if (def.extend && Object.keys( def ).length === 1)
1888
+ xsn.$syntax = 'empty'; // for Warning instead Error with undefined ref
1895
1889
  return (def.extend) ? 'extend' : 'annotate';
1896
1890
  }
1897
1891
  const kind = (def.kind === 'view') ? 'entity' : def.kind; // 'view' is CSN v0.1.0
@@ -13,7 +13,8 @@
13
13
 
14
14
  const { locationString } = require('../base/messages');
15
15
  const { isBetaEnabled } = require('../base/specialOptions');
16
- const { pathName, hasSpecialPathItemProp } = require('../compiler/utils');
16
+ const { pathName, hasSpecialPathItemProp, isLeadingQuery } = require('../compiler/utils');
17
+ const { dictFirst } = require('../compiler/dictionaries');
17
18
  const { CompilerAssertion } = require('../base/error');
18
19
 
19
20
  const compilerVersion = require('../../package.json').version;
@@ -70,6 +71,7 @@ const transformers = {
70
71
  csn[q.val] = true;
71
72
  },
72
73
  all: ignore, // XSN TODO use quantifier
74
+ one: value,
73
75
  // type properties (without 'elements') ------------------------------------
74
76
  localized: value,
75
77
  type,
@@ -114,6 +116,7 @@ const transformers = {
114
116
  rows: expression,
115
117
  offset: expression,
116
118
  on: onCondition,
119
+ $backlink: backlink,
117
120
  // definitions, extensions, members ----------------------------------------
118
121
  notNull: value,
119
122
  default: expression,
@@ -248,10 +251,10 @@ function compactModel( model, options = model.options || {} ) {
248
251
  set( 'i18n', csn, model );
249
252
  set( 'sources', csn, model );
250
253
  // Set $location, use $extra properties of first source as resulting $extra properties
251
- const firstSourceName = Object.keys( srcDict )[0];
252
- if (firstSourceName) {
253
- const firstSource = srcDict[firstSourceName];
254
+ const firstSource = dictFirst( srcDict );
255
+ if (firstSource) {
254
256
  const loc = firstSource.location;
257
+
255
258
  if (loc && loc.file) {
256
259
  Object.defineProperty( csn, '$location', {
257
260
  value: { file: loc.file }, configurable: true, writable: true, enumerable: withLocations,
@@ -545,7 +548,7 @@ function enumDict( dict, csn, node ) {
545
548
  }
546
549
 
547
550
  function enumerableQueryElements( select ) {
548
- return (universalCsn && select !== select._main._leadingQuery);
551
+ return (universalCsn && !isLeadingQuery( select ));
549
552
  }
550
553
 
551
554
  // Should we render the elements? (and enum, items?)
@@ -688,16 +691,17 @@ function dictionary( dict, keys, prop ) {
688
691
  function foreignKeys( dict, csn, node ) {
689
692
  if (!dict || // `Association to many Target` without specified keys
690
693
  universalCsn && dict[$inferred] === 'keys' ||
691
- !target( node.target, csn, node ) )
694
+ !target( node.target, csn, node ) ||
695
+ gensrcFlavor && dict[$inferred])
692
696
  return;
697
+ fkeys( dict, csn );
698
+ }
693
699
 
694
- if (gensrcFlavor) {
695
- if (dict[$inferred])
696
- return;
697
- }
700
+ function fkeys( dict, csn = {} ) {
698
701
  csn.keys = [];
699
702
  for (const n in dict)
700
703
  csn.keys.push( definition( dict[n] ) );
704
+ return csn;
701
705
  }
702
706
 
703
707
  function returns( art, csn, node, prop ) {
@@ -733,21 +737,6 @@ function definition( art, csn, _node, prop ) {
733
737
  return c;
734
738
  }
735
739
 
736
- /**
737
- * Create $origin specification for query/projection.
738
- */
739
- function queryOrigin( xsn ) {
740
- const source = xsn._from[0]._origin;
741
- let $origin;
742
- if (xsn.includes)
743
- // includesOrigin() does originRef() on the first include.
744
- // Use it to behave the same as entity includes.
745
- $origin = includesOrigin( [ { _artifact: source }, ...xsn.includes ], xsn );
746
- else
747
- $origin = originRef( source );
748
- return $origin;
749
- }
750
-
751
740
  /**
752
741
  * Create $origin specification for `includes` of `art`.
753
742
  */
@@ -807,9 +796,16 @@ function addOrigin( csn, xsn, node ) {
807
796
  csn.$source = null;
808
797
  return;
809
798
  }
810
- if (xsn._from) {
811
- const source = xsn._from[0]._origin;
812
- csn.$origin = queryOrigin( xsn );
799
+ if (xsn.query) {
800
+ let source = xsn._origin; // table alias of leading query
801
+ while (source?._main) // source is still a query
802
+ source = source._origin;
803
+ if (!source)
804
+ return;
805
+ csn.$origin = (xsn.includes)
806
+ ? includesOrigin( [ { _artifact: source }, ...xsn.includes ], xsn )
807
+ : originRef( source );
808
+
813
809
  if (source.params && !xsn.params)
814
810
  csn.params = null; // discontinue `params` inheritance
815
811
  if (source.actions && !xsn.actions)
@@ -843,7 +839,7 @@ function addOrigin( csn, xsn, node ) {
843
839
  // console.log( 'X:',xsn, origin, parent, parentOrigin, getParent( origin ) );
844
840
  if (!origin) {
845
841
  if (parent && parentOrigin &&
846
- (parent.kind !== 'select' || parent === parent._main._leadingQuery) &&
842
+ (parent.kind !== 'select' || isLeadingQuery( parent )) &&
847
843
  !(parent.enum && !parent.$origin && parent.type))
848
844
  csn.$origin = null;
849
845
  return;
@@ -937,7 +933,7 @@ function inferredPropertiesForOrigin( csn, node ) {
937
933
  function getParent( art ) {
938
934
  const parent = art._parent;
939
935
  const main = parent._main;
940
- return (main && parent === main._leadingQuery) ? main : parent;
936
+ return (main && isLeadingQuery( parent )) ? main : parent;
941
937
  }
942
938
 
943
939
  function isMember( art ) {
@@ -952,15 +948,18 @@ function isMember( art ) {
952
948
  // return main;
953
949
  // }
954
950
 
955
- // XSN `_origin` is (currently?) not the same as _origin in Universal CSN...
951
+ // XSN `_origin` is not the same as _origin in Universal CSN...
956
952
  // TODO: at least with expand, set it correctly (alias: keep, assoc: to entity, $builtin: no)
957
953
  function getOrigin( art ) {
958
954
  if (art.$noOrigin)
959
955
  return undefined;
960
956
  const { _origin } = art;
961
- if (_origin) // also for query entities
962
- return (_origin.kind === 'builtin') ? undefined : _origin;
963
-
957
+ if (_origin) { // also for query entities
958
+ // eslint-disable-next-line no-nested-ternary
959
+ return (_origin.kind === 'builtin')
960
+ ? undefined
961
+ : (_origin.kind === '$tableAlias') ? _origin._origin : _origin;
962
+ }
964
963
  if (hasExplicitProp( art.type, 'cast' ))
965
964
  return art.type._artifact;
966
965
  // must come after checking _origin, since entities can have both queries and
@@ -994,7 +993,7 @@ function originRef( art, user ) {
994
993
  r.push( !nkind ? name.id : name.id ? { [nkind]: name.id } : { returns: true } );
995
994
  parent = parent._parent;
996
995
  }
997
- if (user && parent._main && parent._main === user._main && parent !== user._main._leadingQuery)
996
+ if (user && parent._main && parent._main === user._main && !isLeadingQuery( parent ))
998
997
  // well, an element of an query in FROM (TODO: try with sub elem), but not the leading query
999
998
  return false; // do not write, probably use $origin: {...}
1000
999
  // for sub query in FROM in sub query in FROM, we could condense the info
@@ -1239,6 +1238,12 @@ function onCondition( cond ) {
1239
1238
  return condition( cond );
1240
1239
  }
1241
1240
 
1241
+ function backlink( back, _csn, xsn ) {
1242
+ if (back._redirected?.length && !gensrcFlavor && xsn?._main?.kind === 'entity')
1243
+ return (back.on) ? condition( back.on ) : fkeys( back.foreignKeys );
1244
+ return undefined;
1245
+ }
1246
+
1242
1247
  function condition( node ) {
1243
1248
  const expr = exprInternal( node, 'no' );
1244
1249
  return (Array.isArray( expr ))
@@ -1309,9 +1314,17 @@ function exprInternal( node, xprParens ) {
1309
1314
  return cast( expression( node.args[0] ), node );
1310
1315
  case 'list':
1311
1316
  return extra( { list: node.args.map( expression ) }, node, 0 );
1317
+ case 'and':
1318
+ for (const arg of node.args) {
1319
+ if (arg.$parens?.length)
1320
+ continue;
1321
+ if ((arg.op?.val === 'nary' || arg.op?.val === 'ixpr') &&
1322
+ arg.args[1]?.val === 'or' &&
1323
+ arg.args[1]?.literal === 'token')
1324
+ arg.$parens = [ arg.location ];
1325
+ }
1326
+ // FALLTHROUGH
1312
1327
  default: { // CSN v0 input (A2J: '='/'and'): binary (n-ary) and unary prefix
1313
- if (!node.args.length)
1314
- return { xpr: [] };
1315
1328
  const nary = [];
1316
1329
  for (const item of node.args)
1317
1330
  nary.push( { val, literal: 'token' }, item );
@@ -1323,10 +1336,16 @@ function exprInternal( node, xprParens ) {
1323
1336
  };
1324
1337
  }
1325
1338
  }
1339
+ if (!node.args?.length)
1340
+ return { xpr: [] };
1326
1341
  const rargs = node.args.map( exprInternal );
1327
1342
  if (val === 'xpr' || node.$parens)
1328
1343
  return extra( { xpr: flattenInternalXpr( rargs, val ) }, node, (xprParens === 'no' ? 0 : 1) );
1329
- return rargs.length === 1 ? rargs[0] : flattenInternalXpr( rargs, val );
1344
+ // An 1-item 'ixpr' or 'nary' can (in general) be replaced by that one item.
1345
+ // For lower *.sql diffs, not for 'xpr' in 'ixpr', produced before A2J recompilation.
1346
+ return rargs.length === 1 && !rargs[0].xpr
1347
+ ? rargs[0]
1348
+ : flattenInternalXpr( rargs, val );
1330
1349
  }
1331
1350
 
1332
1351
 
@@ -1391,7 +1410,7 @@ function query( node, csn, xsn, _prop, expectedParens = 0 ) {
1391
1410
  const select = { SELECT: extra( standard( node ), node, expectedParens ) };
1392
1411
  // one paren pair is not put into XSN - TODO: change that?
1393
1412
  const elems = node.elements;
1394
- if (elems && node._main && node !== node._main._leadingQuery && gensrcFlavor !== true) {
1413
+ if (elems && node._main && !isLeadingQuery( node ) && gensrcFlavor !== true) {
1395
1414
  // Set hidden 'elements' for csnRefs.js. In select-item subqueries,
1396
1415
  // gensrcFlavor might have been set to 'column' and must be set to the
1397
1416
  // original value 'false' - otherwise no element appears.
@@ -345,6 +345,14 @@ declare namespace compiler {
345
345
  * @default true
346
346
  */
347
347
  resolveProjections?: boolean
348
+ /**
349
+ * If true, stringify annotation expression nodes as CDL-like text.
350
+ *
351
+ * Only expression-shaped nodes are stringified. Other annotation values stay unchanged.
352
+ *
353
+ * @default false
354
+ */
355
+ stringifyAnnoXpr?: boolean
348
356
  /**
349
357
  * If true, remap OData annotations to ABAP annotations.
350
358
  *
@@ -200,6 +200,7 @@ module.exports = {
200
200
  compile: (...args) => compiler.compileX(...args),
201
201
  compileSync: (...args) => compiler.compileSyncX(...args),
202
202
  getArtifactName: art => base.getArtifactName(art),
203
+ getOrigin: art => (art._origin?.kind === '$tableAlias' ? art._origin._origin : art._origin),
203
204
  traverseSemanticTokens: (xsn, options) => lsp.traverseSemanticTokens(xsn, options),
204
205
  getSemanticTokenOrigin: obj => lsp.getSemanticTokenOrigin(obj),
205
206
  xsnToCsn: ( xsn, options ) => toCsn.compactModel( xsn, options ),
@@ -926,6 +926,8 @@ function setDependencies( csn ) {
926
926
  const cleanup = [];
927
927
 
928
928
  forEachDefinition(csn, (artifact, artifactName) => {
929
+ if (!isPersistedOnDatabase(artifact))
930
+ return;
929
931
  const queries = getNormalizedQuery(artifact).query;
930
932
  if (queries) {
931
933
  initDependencies(artifact);
@@ -1193,7 +1193,8 @@ class AstBuildingParser extends BaseParser {
1193
1193
  // see also isAnnotationExpression()
1194
1194
  if (!dict['=']) {
1195
1195
  const prop = dict['#'] && '#' ||
1196
- dict.xpr && Object.keys( dict ).length === 1 && 'xpr';
1196
+ dict.xpr && Object.keys( dict ).length === 1 && 'xpr' ||
1197
+ dict['...'] && Object.keys( dict ).length === 1 && '...';
1197
1198
  if (!prop)
1198
1199
  return;
1199
1200
  this.error( 'syntax-invalid-anno-struct', dict[prop].name.location,
@@ -262,8 +262,16 @@ function splitClauses( tree, isCsn ) {
262
262
  return (new XprTree( null, tree, !!isCsn || tree.location )).splitClauses();
263
263
  }
264
264
 
265
+ // Operators that make an expression a predicate (condition) rather than a value.
266
+ const MAX_PREDICATE_PRECEDENCE = 13;
267
+ const predicateOperators = new Set( [
268
+ ...Object.keys( binaryOperators ).filter( op => binaryOperators[op] <= MAX_PREDICATE_PRECEDENCE ),
269
+ 'exists', 'not',
270
+ ] );
271
+
265
272
  module.exports = {
266
273
  xsnAsTree: xprAsTree,
267
274
  csnAsTree: nodes => xprAsTree( nodes, nodes, true ),
268
275
  splitClauses,
276
+ predicateOperators,
269
277
  };
@@ -22,6 +22,7 @@ const { normalizeTypeRef, forEachDefinition } = require('../model/csnUtils');
22
22
  const enrichUniversalCsn = require('../transform/universalCsn/universalCsnEnricher');
23
23
  const { isBetaEnabled } = require('../base/specialOptions');
24
24
  const { ModelError, CompilerAssertion } = require('../base/error');
25
+ const { makeMessageFunction } = require('../base/messages');
25
26
  const { typeParameters, specialFunctions } = require('../compiler/builtins');
26
27
  const { isAnnotationExpression } = require('../base/builtins');
27
28
  const { forEach } = require('../utils/objectUtils');
@@ -2032,7 +2033,7 @@ class CsnToCdl {
2032
2033
  : this.quotePathIfRequired(annoValue['='], env);
2033
2034
  }
2034
2035
  // Ellipsis: `... up to <val>`
2035
- if (annoValue['...'] !== undefined) {
2036
+ if (annoValue['...'] !== undefined && Object.keys( annoValue ).length === 1) {
2036
2037
  return (annoValue['...'] === true)
2037
2038
  ? '...'
2038
2039
  : `... up to ${ this.renderAnnotationValue(annoValue['...'], env) }`;
@@ -2714,7 +2715,10 @@ class CsnToCdl {
2714
2715
  * @param {CdlRenderEnvironment} env
2715
2716
  * @returns {string}
2716
2717
  */
2718
+ // TODO: not quite sure why we split at '.' when quoting is needed
2717
2719
  quoteAnnotationPathIfRequired( anno, env ) {
2720
+ if (anno === '...')
2721
+ return this.quoteNonIdentifier(anno, env);
2718
2722
  return anno.split('.').map((segment) => {
2719
2723
  if (segment.startsWith('@'))
2720
2724
  return `@${ this.quoteNonIdentifier(segment.slice(1), env) }`;
@@ -3075,9 +3079,26 @@ function csnToCdl( csn, options, msg ) {
3075
3079
  return renderer.render();
3076
3080
  }
3077
3081
 
3082
+ /**
3083
+ * Render a CSN expression object to CDL-like text.
3084
+ *
3085
+ * @param {object} expr CSN expression node
3086
+ * @param {CdlOptions} [options]
3087
+ * @param {object} [msg] Message functions
3088
+ * @returns {string}
3089
+ */
3090
+ function expressionToCdlString( expr, options = {}, msg = null ) {
3091
+ const model = { $version: '2.0', definitions: Object.create(null) };
3092
+ const messageFunctions = msg || makeMessageFunction(model, options, 'to-cdl');
3093
+ const renderer = new CsnToCdl(model, options, messageFunctions);
3094
+ const env = createEnv({ path: [] });
3095
+ env.nameEnvStack.setRootScope(new DefinitionPathTree(), model);
3096
+ return renderer.exprRenderer.renderExpr(expr, env);
3097
+ }
3078
3098
 
3079
3099
  module.exports = {
3080
3100
  csnToCdl,
3101
+ expressionToCdlString,
3081
3102
  smartId: apiSmartId,
3082
3103
  smartFunctionId: apiSmartFunctionId,
3083
3104
  delimitedId: apiDelimitedId,
@@ -31,7 +31,7 @@ const { manageConstraints, manageConstraint } = require('./manageConstraints');
31
31
  const { renderUniqueConstraintString, renderUniqueConstraintDrop, renderUniqueConstraintAdd } = require('./utils/unique');
32
32
  const { ModelError, CompilerAssertion } = require('../base/error');
33
33
  const { pathId } = require('../base/csnRefs');
34
- const { transformExprOperators } = require('./utils/operators');
34
+ const { transformExprOperators, isTopLevelPredicate } = require('./utils/operators');
35
35
  const { exprAsTree, condAsTree } = require('../base/xprAsTree');
36
36
 
37
37
  class SqlRenderEnvironment {
@@ -1183,7 +1183,10 @@ function toSqlDdl( csn, options, messageFunctions ) {
1183
1183
  if (!col.as && col.ref?.[0] && isMagicVariable(pathId(col.ref?.[0])))
1184
1184
  col.as = implicitAs(col.ref);
1185
1185
 
1186
- result = env.indent + renderExpr(withoutCast(col), env);
1186
+ // HANA rejects bare predicates in the select list; wrap them in CASE … WHEN.
1187
+ result = env.indent + ((options.sqlDialect === 'hana' && isTopLevelPredicate(col))
1188
+ ? wrapPredicateInCase(renderExpr({ xpr: col.xpr }, env))
1189
+ : renderExpr(withoutCast(col), env));
1187
1190
  if (col.as)
1188
1191
  result += ` AS ${ quoteSqlId(col.as) }`;
1189
1192
  else if (col.func && !col.args) // e.g. CURRENT_TIMESTAMP
@@ -1728,6 +1731,18 @@ function toSqlDdl( csn, options, messageFunctions ) {
1728
1731
  }
1729
1732
  }
1730
1733
 
1734
+ /**
1735
+ * Wrap a rendered predicate in `CASE WHEN <p> THEN TRUE WHEN NOT (<p>) THEN FALSE
1736
+ * END`, as HANA requires for a predicate in the select list. The negated `WHEN`
1737
+ * (not an `ELSE`) keeps a NULL predicate result as NULL rather than FALSE.
1738
+ *
1739
+ * @param {string} predicate Rendered predicate SQL
1740
+ * @return {string}
1741
+ */
1742
+ function wrapPredicateInCase( predicate ) {
1743
+ return `CASE WHEN (${ predicate }) THEN TRUE WHEN NOT (${ predicate }) THEN FALSE END`;
1744
+ }
1745
+
1731
1746
  /**
1732
1747
  * Render the given string for SQL databases.
1733
1748
  *
@@ -41,7 +41,12 @@ function renderFunc( funcName, node, renderArgs, utils ) {
41
41
  if (rewriteStandardFunctions) {
42
42
  // we check function arguments for correctness
43
43
  const { error } = messageFunctions;
44
- const that = { renderArgs, error, path };
44
+ const that = {
45
+ renderArgs,
46
+ error,
47
+ path,
48
+ vector: { embeddingDefaultModel: options.vectorEmbeddingDefaultModel ?? 'SAP_GXY.20250407', embeddingHanaDefaultRemoteSource: options.vectorEmbeddingHanaDefaultRemoteSource ?? 'AI_CORE' },
49
+ };
45
50
  if (standardDatabaseFunctions[sqlDialect]?.[funcName])
46
51
  return standardDatabaseFunctions[sqlDialect][funcName].call(that, node);
47
52
  else if (standardDatabaseFunctions.common[funcName])
@@ -2,6 +2,8 @@
2
2
 
3
3
  // Utilities to transform operators in expressions for SQL rendering.
4
4
 
5
+ const { csnAsTree, predicateOperators } = require('../../parsers/XprTree');
6
+
5
7
  const operatorsPerDialect = {
6
8
  __proto__: null,
7
9
  plain: {
@@ -155,6 +157,31 @@ function transformExprOperators( xpr, options, messageFunctions, env ) {
155
157
  }
156
158
  }
157
159
 
160
+ /**
161
+ * Whether the outermost operator of a column expression is a predicate (condition).
162
+ * Clones first because csnAsTree() restructures its input in place, and the column
163
+ * is structurized again for real when it is rendered.
164
+ *
165
+ * @param {object} col CSN column
166
+ * @returns {boolean}
167
+ */
168
+ function isTopLevelPredicate( col ) {
169
+ if (!Array.isArray(col.xpr))
170
+ return false;
171
+ return isPredicateTree(csnAsTree(structuredClone(col.xpr)));
172
+ }
173
+
174
+ function isPredicateTree( tree ) {
175
+ const [ top ] = tree;
176
+ if (top && !Array.isArray(top) && top.xpr) // fully parenthesized: `( … )`
177
+ return isPredicateTree(csnAsTree(top.xpr));
178
+ if (!Array.isArray(top))
179
+ return false;
180
+ const op = typeof top[0] === 'string' ? top[0] : top[1];
181
+ return predicateOperators.has(op);
182
+ }
183
+
158
184
  module.exports = {
159
185
  transformExprOperators,
186
+ isTopLevelPredicate,
160
187
  };