@sap/cds 5.9.8 → 6.0.3

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 (381) hide show
  1. package/CHANGELOG.md +277 -20
  2. package/apis/services.d.ts +1 -1
  3. package/app/fiori/preview.js +2 -6
  4. package/app/index.js +3 -3
  5. package/bin/build/buildTaskEngine.js +17 -15
  6. package/bin/build/buildTaskFactory.js +29 -19
  7. package/bin/build/buildTaskHandler.js +27 -11
  8. package/bin/build/buildTaskProvider.js +2 -4
  9. package/bin/build/buildTaskProviderFactory.js +11 -16
  10. package/bin/build/constants.js +14 -6
  11. package/bin/build/csv-reader.js +2 -1
  12. package/bin/build/index.js +12 -18
  13. package/bin/build/provider/buildTaskHandlerEdmx.js +3 -39
  14. package/bin/build/provider/buildTaskHandlerFeatureToggles.js +149 -0
  15. package/bin/build/provider/buildTaskHandlerInternal.js +2 -3
  16. package/bin/build/provider/buildTaskProviderInternal.js +108 -239
  17. package/bin/build/provider/fiori/index.js +2 -2
  18. package/bin/build/provider/hana/2migration.js +11 -11
  19. package/bin/build/provider/hana/2tabledata.js +3 -3
  20. package/bin/build/provider/hana/index.js +89 -99
  21. package/bin/build/provider/hana/migrationtable.js +4 -3
  22. package/bin/build/provider/java/index.js +101 -0
  23. package/bin/build/provider/java-cf/index.js +1 -101
  24. package/bin/build/provider/mtx/index.js +83 -41
  25. package/bin/build/provider/mtx/resourcesTarBuilder.js +68 -0
  26. package/bin/build/provider/mtx-sidecar/index.js +110 -0
  27. package/bin/build/provider/node-cf/index.js +1 -308
  28. package/bin/build/provider/nodejs/index.js +189 -0
  29. package/bin/build/util.js +21 -31
  30. package/bin/cds.js +5 -3
  31. package/bin/deploy/to-hana/cfUtil.js +31 -6
  32. package/bin/deploy/to-hana/gitUtil.js +5 -3
  33. package/bin/deploy/to-hana/hana.js +15 -13
  34. package/bin/{build → deploy/to-hana}/mtaUtil.js +10 -9
  35. package/bin/mtx/in-cds.js +19 -7
  36. package/bin/serve.js +49 -22
  37. package/bin/utils/log.js +13 -30
  38. package/bin/version.js +4 -3
  39. package/common.cds +61 -16
  40. package/lib/compile/cdsc.js +3 -2
  41. package/lib/compile/etc/_localized.js +15 -14
  42. package/lib/compile/for/drafts.js +3 -4
  43. package/lib/compile/for/java.js +13 -10
  44. package/lib/compile/for/nodejs.js +8 -8
  45. package/lib/compile/for/odata.js +7 -12
  46. package/lib/compile/for/sql.js +5 -6
  47. package/lib/compile/index.js +5 -4
  48. package/lib/compile/load.js +9 -11
  49. package/lib/compile/minify.js +8 -5
  50. package/lib/compile/parse.js +4 -2
  51. package/lib/compile/resolve.js +18 -15
  52. package/lib/compile/to/edm.js +0 -1
  53. package/lib/compile/to/gql.js +3 -2
  54. package/lib/compile/to/json.js +24 -17
  55. package/lib/connect/bindings.js +3 -2
  56. package/lib/connect/index.js +5 -5
  57. package/lib/core/classes.js +74 -2
  58. package/lib/core/entities.js +52 -3
  59. package/lib/core/reflect.js +2 -1
  60. package/lib/deploy.js +10 -8
  61. package/lib/env/defaults.js +4 -3
  62. package/lib/env/index.js +71 -31
  63. package/lib/env/presets.js +1 -14
  64. package/lib/env/requires.js +71 -20
  65. package/lib/env/serviceBindings.js +147 -0
  66. package/lib/i18n/localize.js +22 -23
  67. package/lib/index.js +148 -144
  68. package/lib/log/errors.js +55 -12
  69. package/lib/log/format/kibana.js +1 -1
  70. package/lib/log/index.js +4 -0
  71. package/lib/ql/SELECT.js +7 -2
  72. package/lib/ql/Whereable.js +8 -2
  73. package/lib/ql/index.js +2 -2
  74. package/lib/req/assert.js +71 -0
  75. package/lib/req/cds-context.js +38 -70
  76. package/lib/req/context.js +34 -21
  77. package/lib/req/request.js +12 -18
  78. package/lib/req/response.js +6 -2
  79. package/lib/req/user.js +30 -22
  80. package/lib/serve/Service-api.js +17 -12
  81. package/lib/serve/Service-dispatch.js +5 -9
  82. package/lib/serve/Service-methods.js +4 -3
  83. package/lib/serve/Transaction.js +24 -21
  84. package/lib/serve/adapters.js +15 -5
  85. package/lib/serve/factory.js +22 -20
  86. package/lib/serve/index.js +51 -54
  87. package/lib/utils/axios.js +8 -12
  88. package/lib/utils/index.js +13 -4
  89. package/lib/utils/resources/index.js +1 -44
  90. package/lib/utils/resources/tar.js +2 -1
  91. package/lib/utils/tests.js +13 -15
  92. package/libx/_runtime/.eslintrc +1 -1
  93. package/libx/_runtime/audit/Service.js +6 -4
  94. package/libx/_runtime/audit/generic/personal/access.js +19 -43
  95. package/libx/_runtime/audit/generic/personal/index.js +40 -34
  96. package/libx/_runtime/audit/generic/personal/modification.js +11 -9
  97. package/libx/_runtime/audit/generic/personal/utils.js +13 -6
  98. package/libx/_runtime/audit/utils/v2.js +6 -3
  99. package/libx/_runtime/auth/index.js +71 -66
  100. package/libx/_runtime/auth/strategies/JWT.js +3 -2
  101. package/libx/_runtime/auth/strategies/mock.js +54 -53
  102. package/libx/_runtime/auth/strategies/xssecUtils.js +3 -4
  103. package/libx/_runtime/auth/strategies/xsuaa.js +3 -2
  104. package/libx/_runtime/auth/utils.js +2 -15
  105. package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +127 -41
  106. package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +9 -5
  107. package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +93 -73
  108. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +25 -45
  109. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +10 -14
  110. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +9 -5
  111. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +4 -2
  112. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +60 -53
  113. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +2 -2
  114. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +21 -26
  115. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +8 -15
  116. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/expandToCQN.js +29 -41
  117. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/index.js +1 -4
  118. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/readToCQN.js +13 -13
  119. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/selectToCQN.js +0 -7
  120. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/utils.js +24 -1
  121. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/edm/EdmEntityContainer.js +1 -1
  122. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/UriHelper.js +4 -3
  123. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/utils/PrimitiveValueDecoder.js +4 -5
  124. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/utils/ValueConverter.js +4 -3
  125. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/validator/ValueValidator.js +5 -3
  126. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/core/ResponseHeaderSetter.js +2 -0
  127. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/DebugSerializingCommand.js +1 -1
  128. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/PresetResponseHeadersCommand.js +1 -1
  129. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/SerializingCommand.js +1 -1
  130. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/SetResponseHeadersCommand.js +1 -1
  131. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/ContextURLFactory.js +3 -2
  132. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/ErrorJsonSerializer.js +3 -1
  133. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/SerializerFactory.js +1 -0
  134. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/TrustedResourceJsonSerializer.js +3 -3
  135. package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +36 -25
  136. package/libx/_runtime/cds-services/adapter/odata-v4/utils/handlerUtils.js +97 -92
  137. package/libx/_runtime/cds-services/adapter/odata-v4/utils/metaInfo.js +382 -0
  138. package/libx/_runtime/cds-services/adapter/odata-v4/utils/oDataConfiguration.js +1 -4
  139. package/libx/_runtime/cds-services/adapter/odata-v4/utils/omitValues.js +5 -6
  140. package/libx/_runtime/cds-services/adapter/odata-v4/utils/readAfterWrite.js +82 -21
  141. package/libx/_runtime/cds-services/adapter/odata-v4/utils/request.js +3 -11
  142. package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +91 -69
  143. package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +27 -6
  144. package/libx/_runtime/cds-services/adapter/rest/utils/validation-checks.js +7 -17
  145. package/libx/_runtime/cds-services/services/Service.js +17 -76
  146. package/libx/_runtime/cds-services/services/utils/columns.js +6 -4
  147. package/libx/_runtime/cds-services/services/utils/compareJson.js +1 -53
  148. package/libx/_runtime/cds-services/services/utils/differ.js +15 -19
  149. package/libx/_runtime/cds-services/util/assert.js +107 -34
  150. package/libx/_runtime/cds.js +1 -31
  151. package/libx/_runtime/common/aspects/Association.js +40 -54
  152. package/libx/_runtime/common/aspects/any.js +61 -6
  153. package/libx/_runtime/common/aspects/entity.js +19 -79
  154. package/libx/_runtime/common/composition/data.js +2 -2
  155. package/libx/_runtime/common/composition/delete.js +8 -7
  156. package/libx/_runtime/common/composition/tree.js +10 -10
  157. package/libx/_runtime/common/composition/update.js +3 -2
  158. package/libx/_runtime/common/constants/events.js +13 -0
  159. package/libx/_runtime/common/error/entry.js +9 -3
  160. package/libx/_runtime/common/error/frontend.js +13 -19
  161. package/libx/_runtime/common/error/index.js +8 -3
  162. package/libx/_runtime/common/generic/auth/capabilities.js +2 -1
  163. package/libx/_runtime/common/generic/auth/constants.js +1 -4
  164. package/libx/_runtime/common/generic/auth/requires.js +1 -1
  165. package/libx/_runtime/common/generic/auth/restrict.js +12 -28
  166. package/libx/_runtime/common/generic/auth/restrictions.js +12 -4
  167. package/libx/_runtime/common/generic/auth/utils.js +2 -1
  168. package/libx/_runtime/common/generic/crud.js +9 -60
  169. package/libx/_runtime/common/generic/etag.js +41 -7
  170. package/libx/_runtime/common/generic/input.js +128 -66
  171. package/libx/_runtime/common/generic/paging.js +9 -3
  172. package/libx/_runtime/common/generic/put.js +2 -2
  173. package/libx/_runtime/common/generic/sorting.js +7 -3
  174. package/libx/_runtime/common/generic/temporal.js +0 -5
  175. package/libx/_runtime/common/i18n/messages.properties +2 -1
  176. package/libx/_runtime/common/utils/binary.js +69 -0
  177. package/libx/_runtime/common/utils/cqn.js +39 -14
  178. package/libx/_runtime/common/utils/cqn2cqn4sql.js +93 -59
  179. package/libx/_runtime/common/utils/csn.js +87 -85
  180. package/libx/_runtime/common/utils/dollar.js +8 -7
  181. package/libx/_runtime/common/utils/draft.js +1 -1
  182. package/libx/_runtime/common/utils/foreignKeyPropagations.js +23 -7
  183. package/libx/_runtime/common/utils/generateOnCond.js +2 -1
  184. package/libx/_runtime/common/utils/keys.js +30 -13
  185. package/libx/_runtime/common/utils/postProcessing.js +6 -1
  186. package/libx/_runtime/common/utils/quotingStyles.js +0 -23
  187. package/libx/_runtime/common/utils/resolveStructured.js +23 -26
  188. package/libx/_runtime/common/utils/resolveView.js +4 -1
  189. package/libx/_runtime/common/utils/rewriteAsterisks.js +3 -0
  190. package/libx/_runtime/common/utils/search2cqn4sql.js +4 -13
  191. package/libx/_runtime/common/utils/searchToLike.js +9 -13
  192. package/libx/_runtime/common/utils/streamProp.js +35 -0
  193. package/libx/_runtime/common/utils/structured.js +12 -18
  194. package/libx/_runtime/common/utils/template.js +3 -5
  195. package/libx/_runtime/common/utils/templateProcessor.js +22 -14
  196. package/libx/_runtime/common/utils/unionCqnTemplate.js +4 -14
  197. package/libx/_runtime/db/Service.js +2 -1
  198. package/libx/_runtime/db/expand/expand-v2.js +2 -2
  199. package/libx/_runtime/db/expand/expandCQNToJoin.js +7 -6
  200. package/libx/_runtime/db/generic/input.js +14 -17
  201. package/libx/_runtime/db/generic/integrity.js +1 -2
  202. package/libx/_runtime/db/generic/update.js +14 -1
  203. package/libx/_runtime/db/query/read.js +0 -1
  204. package/libx/_runtime/db/query/update.js +1 -1
  205. package/libx/_runtime/db/sql-builder/BaseBuilder.js +1 -1
  206. package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +5 -31
  207. package/libx/_runtime/db/sql-builder/InsertBuilder.js +1 -1
  208. package/libx/_runtime/db/sql-builder/ReferenceBuilder.js +0 -9
  209. package/libx/_runtime/db/sql-builder/SelectBuilder.js +11 -10
  210. package/libx/_runtime/db/sql-builder/UpdateBuilder.js +2 -2
  211. package/libx/_runtime/db/sql-builder/annotations.js +1 -2
  212. package/libx/_runtime/db/utils/coloredTxCommands.js +5 -0
  213. package/libx/_runtime/db/utils/columns.js +1 -1
  214. package/libx/_runtime/db/utils/propagateForeignKeys.js +10 -2
  215. package/libx/_runtime/extensibility/activate.js +69 -0
  216. package/libx/_runtime/extensibility/add.js +41 -0
  217. package/libx/_runtime/extensibility/addExtension.js +68 -0
  218. package/libx/_runtime/extensibility/defaults.js +39 -0
  219. package/libx/_runtime/extensibility/{uiflex/handler → handler}/transformREAD.js +0 -0
  220. package/libx/_runtime/extensibility/{uiflex/handler → handler}/transformRESULT.js +2 -2
  221. package/libx/_runtime/extensibility/{uiflex/handler → handler}/transformWRITE.js +2 -2
  222. package/libx/_runtime/extensibility/push.js +61 -0
  223. package/libx/_runtime/extensibility/service.js +21 -0
  224. package/libx/_runtime/extensibility/{uiflex/utils.js → utils.js} +39 -3
  225. package/libx/_runtime/extensibility/validation.js +53 -0
  226. package/libx/_runtime/extensibility/views.js +12 -0
  227. package/libx/_runtime/fiori/generic/activate.js +2 -4
  228. package/libx/_runtime/fiori/generic/before.js +17 -29
  229. package/libx/_runtime/fiori/generic/cancel.js +2 -4
  230. package/libx/_runtime/fiori/generic/delete.js +2 -4
  231. package/libx/_runtime/fiori/generic/edit.js +4 -16
  232. package/libx/_runtime/fiori/generic/index.js +31 -0
  233. package/libx/_runtime/fiori/generic/new.js +5 -21
  234. package/libx/_runtime/fiori/generic/patch.js +10 -15
  235. package/libx/_runtime/fiori/generic/prepare.js +13 -22
  236. package/libx/_runtime/fiori/generic/read.js +148 -163
  237. package/libx/_runtime/fiori/generic/readOverDraft.js +10 -4
  238. package/libx/_runtime/fiori/utils/handler.js +10 -22
  239. package/libx/_runtime/fiori/utils/where.js +1 -4
  240. package/libx/_runtime/hana/Service.js +14 -7
  241. package/libx/_runtime/hana/customBuilder/CustomSelectBuilder.js +1 -1
  242. package/libx/_runtime/hana/dynatrace.js +2 -2
  243. package/libx/_runtime/hana/localized.js +7 -6
  244. package/libx/_runtime/hana/pool.js +9 -6
  245. package/libx/_runtime/hana/search.js +2 -3
  246. package/libx/_runtime/hana/{searchToContains.js → search2Contains.js} +5 -2
  247. package/libx/_runtime/hana/search2cqn4sql.js +20 -17
  248. package/libx/_runtime/index.js +2 -6
  249. package/libx/_runtime/messaging/AMQPWebhookMessaging.js +30 -22
  250. package/libx/_runtime/messaging/common-utils/AMQPClient.js +4 -3
  251. package/libx/_runtime/messaging/common-utils/appId.js +9 -0
  252. package/libx/_runtime/messaging/common-utils/authorizedRequest.js +2 -18
  253. package/libx/_runtime/messaging/common-utils/connections.js +1 -1
  254. package/libx/_runtime/messaging/enterprise-messaging-shared.js +2 -2
  255. package/libx/_runtime/messaging/enterprise-messaging-utils/EMManagement.js +305 -231
  256. package/libx/_runtime/messaging/enterprise-messaging-utils/cloudEvents.js +2 -2
  257. package/libx/_runtime/messaging/enterprise-messaging-utils/options-management.js +15 -8
  258. package/libx/_runtime/messaging/enterprise-messaging-utils/options-messaging.js +57 -14
  259. package/libx/_runtime/messaging/enterprise-messaging.js +14 -19
  260. package/libx/_runtime/messaging/file-based.js +3 -1
  261. package/libx/_runtime/messaging/http-utils/token.js +18 -6
  262. package/libx/_runtime/messaging/message-queuing-utils/options-management.js +22 -12
  263. package/libx/_runtime/messaging/message-queuing-utils/options-messaging.js +27 -14
  264. package/libx/_runtime/messaging/message-queuing.js +138 -85
  265. package/libx/_runtime/messaging/outbox/utils.js +13 -7
  266. package/libx/_runtime/messaging/redis-messaging.js +0 -1
  267. package/libx/_runtime/messaging/service.js +4 -1
  268. package/libx/_runtime/remote/Service.js +24 -18
  269. package/libx/_runtime/remote/utils/client.js +90 -48
  270. package/libx/_runtime/remote/utils/data.js +23 -6
  271. package/libx/_runtime/sqlite/Service.js +14 -13
  272. package/libx/_runtime/sqlite/convertAssocToOneManaged.js +2 -0
  273. package/libx/_runtime/sqlite/customBuilder/CustomSelectBuilder.js +1 -0
  274. package/libx/_runtime/sqlite/execute.js +3 -9
  275. package/libx/_runtime/types/api.js +23 -11
  276. package/libx/common/utils/ucsn.js +15 -9
  277. package/libx/odata/afterburner.js +109 -29
  278. package/libx/odata/cqn2odata.js +48 -9
  279. package/libx/odata/grammar.pegjs +263 -156
  280. package/libx/odata/index.js +21 -9
  281. package/libx/odata/parseToCqn.js +8 -5
  282. package/libx/odata/parser.js +1 -1
  283. package/libx/odata/utils.js +13 -3
  284. package/libx/rest/RestAdapter.js +173 -113
  285. package/libx/rest/RestRequest.js +3 -2
  286. package/libx/rest/middleware/create.js +8 -6
  287. package/libx/rest/middleware/delete.js +6 -13
  288. package/libx/rest/middleware/error.js +1 -1
  289. package/libx/rest/middleware/input.js +6 -6
  290. package/libx/rest/middleware/operation.js +8 -3
  291. package/libx/rest/middleware/parse.js +3 -3
  292. package/libx/rest/middleware/payload.js +12 -0
  293. package/libx/rest/middleware/read.js +12 -2
  294. package/libx/rest/middleware/update.js +3 -3
  295. package/package.json +4 -6
  296. package/server.js +3 -44
  297. package/srv/extensibility-service.cds +56 -0
  298. package/srv/extensibility-service.js +1 -0
  299. package/srv/extensions.cds +8 -0
  300. package/srv/model-provider.cds +59 -0
  301. package/srv/model-provider.js +163 -0
  302. package/srv/mtx.cds +2 -0
  303. package/srv/mtx.js +22 -0
  304. package/srv/outbox.cds +2 -0
  305. package/tasks/enterprise-messaging-deploy.js +19 -12
  306. package/lib/serve/Service-compat.js +0 -36
  307. package/libx/_runtime/audit/generic/personal/constants.js +0 -4
  308. package/libx/_runtime/auth/strategies/dwc.js +0 -45
  309. package/libx/_runtime/cds-services/adapter/odata-v4/utils/dispatcherUtils.js +0 -56
  310. package/libx/_runtime/cds-services/adapter/rest/Rest.js +0 -183
  311. package/libx/_runtime/cds-services/adapter/rest/RestRequest.js +0 -67
  312. package/libx/_runtime/cds-services/adapter/rest/handlers/create.js +0 -82
  313. package/libx/_runtime/cds-services/adapter/rest/handlers/delete.js +0 -39
  314. package/libx/_runtime/cds-services/adapter/rest/handlers/operation.js +0 -63
  315. package/libx/_runtime/cds-services/adapter/rest/handlers/read.js +0 -52
  316. package/libx/_runtime/cds-services/adapter/rest/handlers/update.js +0 -81
  317. package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/index.js +0 -56
  318. package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/utils.js +0 -33
  319. package/libx/_runtime/cds-services/adapter/rest/to.js +0 -8
  320. package/libx/_runtime/cds-services/adapter/rest/utils/binary.js +0 -50
  321. package/libx/_runtime/cds-services/adapter/rest/utils/data.js +0 -117
  322. package/libx/_runtime/cds-services/adapter/rest/utils/header-checks.js +0 -14
  323. package/libx/_runtime/cds-services/adapter/rest/utils/key-value-utils.js +0 -30
  324. package/libx/_runtime/cds-services/adapter/rest/utils/parse-url.js +0 -250
  325. package/libx/_runtime/cds-services/adapter/rest/utils/result.js +0 -26
  326. package/libx/_runtime/cds-services/services/utils/handlerUtils.js +0 -200
  327. package/libx/_runtime/common/aspects/utils.js +0 -152
  328. package/libx/_runtime/common/toggles/handler.js +0 -21
  329. package/libx/_runtime/common/utils/extensibilityUtils.js +0 -18
  330. package/libx/_runtime/extensibility/mps/index.js +0 -5
  331. package/libx/_runtime/extensibility/mps/service.js +0 -111
  332. package/libx/_runtime/extensibility/mps/tar.js +0 -42
  333. package/libx/_runtime/extensibility/mps/utils.js +0 -11
  334. package/libx/_runtime/extensibility/uiflex/index.js +0 -54
  335. package/libx/_runtime/extensibility/uiflex/service.js +0 -276
  336. package/libx/_runtime/messaging/common-utils/naming-conventions.js +0 -20
  337. package/libx/_runtime/remote/utils/client-types.d.ts +0 -7
  338. package/libx/gql/GraphQLAdapter.js +0 -33
  339. package/libx/gql/constants/adapter.js +0 -69
  340. package/libx/gql/constants/cds.js +0 -18
  341. package/libx/gql/constants/graphql.js +0 -33
  342. package/libx/gql/readme.md +0 -1
  343. package/libx/gql/resolvers/crud/create.js +0 -20
  344. package/libx/gql/resolvers/crud/delete.js +0 -29
  345. package/libx/gql/resolvers/crud/index.js +0 -6
  346. package/libx/gql/resolvers/crud/read.js +0 -30
  347. package/libx/gql/resolvers/crud/update.js +0 -42
  348. package/libx/gql/resolvers/crud/utils/index.js +0 -36
  349. package/libx/gql/resolvers/field.js +0 -5
  350. package/libx/gql/resolvers/index.js +0 -7
  351. package/libx/gql/resolvers/mutation.js +0 -23
  352. package/libx/gql/resolvers/parse/ast/enrich.js +0 -52
  353. package/libx/gql/resolvers/parse/ast/fragment.js +0 -11
  354. package/libx/gql/resolvers/parse/ast/fromObject.js +0 -39
  355. package/libx/gql/resolvers/parse/ast/index.js +0 -3
  356. package/libx/gql/resolvers/parse/ast/meta.js +0 -4
  357. package/libx/gql/resolvers/parse/ast/variable.js +0 -7
  358. package/libx/gql/resolvers/parse/ast2cqn/columns.js +0 -44
  359. package/libx/gql/resolvers/parse/ast2cqn/entries.js +0 -31
  360. package/libx/gql/resolvers/parse/ast2cqn/index.js +0 -8
  361. package/libx/gql/resolvers/parse/ast2cqn/limit.js +0 -6
  362. package/libx/gql/resolvers/parse/ast2cqn/orderBy.js +0 -24
  363. package/libx/gql/resolvers/parse/ast2cqn/utils/index.js +0 -3
  364. package/libx/gql/resolvers/parse/ast2cqn/where.js +0 -70
  365. package/libx/gql/resolvers/parse/utils/index.js +0 -8
  366. package/libx/gql/resolvers/query.js +0 -13
  367. package/libx/gql/resolvers/root.js +0 -34
  368. package/libx/gql/schema/generate.js +0 -18
  369. package/libx/gql/schema/index.js +0 -5
  370. package/libx/gql/schema/mutation.js +0 -76
  371. package/libx/gql/schema/query.js +0 -108
  372. package/libx/gql/schema/typeDefMap.js +0 -45
  373. package/libx/gql/schema/utils/index.js +0 -54
  374. package/libx/gql/utils/index.js +0 -12
  375. package/libx/rest/middleware/auth.js +0 -20
  376. package/libx/rest/middleware/content.js +0 -19
  377. package/srv/flex.cds +0 -21
  378. package/srv/flex.js +0 -1
  379. package/srv/mps.cds +0 -23
  380. package/srv/mps.js +0 -1
  381. package/srv/outbox.js +0 -0
@@ -38,6 +38,11 @@ const _modifyCQN = (cqnDraft, where, context) => {
38
38
  const fromRef = cqnDraft.SELECT.from.ref
39
39
  cqnDraft.SELECT.from.ref[fromRef.length - 1] = ensureDraftsSuffix(fromRef[fromRef.length - 1])
40
40
  }
41
+ if (cqnDraft.SELECT.columns) {
42
+ cqnDraft.SELECT.columns = cqnDraft.SELECT.columns.map(e =>
43
+ e.ref && e.ref.includes('IsActiveEntity') ? { val: true, as: 'IsActiveEntity', cast: { type: 'cds.Boolean' } } : e
44
+ )
45
+ }
41
46
 
42
47
  _modifyWhere(cqnDraft.SELECT.where, context)
43
48
  }
@@ -66,8 +71,9 @@ const _shouldReadOverDraft = (req, definitions) => {
66
71
 
67
72
  if (!fromRef) return false
68
73
 
69
- // read over the draft if the navigation target is non-draft-enabled
70
- if (!req.target._isDraftEnabled) return true
74
+ // for $expand requests, read over the draft if the navigation target is non-draft-enabled
75
+ // REVISIT: this is an interim workaround to be removed
76
+ if (!req.target._isDraftEnabled && SELECT.columns && SELECT.columns.some(column => column.expand)) return true
71
77
 
72
78
  // read over the draft only for navigation scenarios
73
79
  if (fromRef.length === 1) return false
@@ -136,6 +142,6 @@ const _readOverDraftHandler = async function (req, next) {
136
142
  return cds.tx(req).run(sqlQuery)
137
143
  }
138
144
 
139
- module.exports = cds.service.impl(function readOverDraft() {
140
- this.on('READ', '*', _readOverDraftHandler)
145
+ module.exports = cds.service.impl(function readOverDraft(srv) {
146
+ srv.on('READ', '*', _readOverDraftHandler)
141
147
  })
@@ -137,17 +137,17 @@ const getEnrichedCQN = (cqn, select, draftWhere, scenarioAlias, addLimitOrder =
137
137
  if (select.one) cqn.SELECT.one = true
138
138
 
139
139
  if (select.having) {
140
- cqn.having(_aliased(select.having, alias))
140
+ cqn.having(_aliased(select.having, select.columns, alias))
141
141
  }
142
142
 
143
143
  // groupBy, orderBy and limit do not support partial CQNs
144
144
  if (select.groupBy) {
145
- cqn.SELECT.groupBy = _aliased(select.groupBy, alias)
145
+ cqn.SELECT.groupBy = _aliased(select.groupBy, select.columns, alias)
146
146
  cqn.SELECT.columns = _getSelectedColumns(cqn.SELECT.columns, select.columns)
147
147
  }
148
148
 
149
149
  if (select.orderBy && addLimitOrder) {
150
- cqn.SELECT.orderBy = _aliased(select.orderBy, alias)
150
+ cqn.SELECT.orderBy = _aliased(select.orderBy, select.columns, alias)
151
151
  }
152
152
 
153
153
  if (select.limit && addLimitOrder) {
@@ -169,24 +169,20 @@ const _aliasRef = (ref, alias) => {
169
169
  const getDeleteDraftAdminCqn = draftUUID =>
170
170
  DELETE.from('DRAFT.DraftAdministrativeData').where([{ ref: ['DraftUUID'] }, '=', { val: draftUUID }])
171
171
 
172
- const _aliased = (arr, alias) =>
172
+ const _aliased = (arr, columns, alias) =>
173
173
  arr.map(item => {
174
- if (alias && item.ref && item.ref[0] !== alias) {
174
+ if (item.ref && columns.some(c => c.as === item.ref[item.ref.length - 1])) {
175
+ // remove table alias if present for a calculated field
176
+ if (item.ref[0] === alias) {
177
+ return item.ref.splice(0, 1)
178
+ }
179
+ } else if (alias && item.ref && item.ref[0] !== alias) {
175
180
  return Object.assign({}, item, { ref: _aliasRef(item.ref, alias) })
176
181
  }
177
182
  return item
178
183
  })
179
184
 
180
185
  // Only works for root entity, otherwise the relative position needs to be adapted
181
- const setStatusCodeAndHeader = (response, keys, entityName, isActiveEntity) => {
182
- response.setStatusCode(201)
183
-
184
- const keysString = Object.keys(keys)
185
- .map(key => `${key}=${keys[key]}`)
186
- .join(',')
187
- response.setHeader('location', `../${entityName}(${keysString},IsActiveEntity=${isActiveEntity})`)
188
- }
189
-
190
186
  const removeDraftUUIDIfNecessary = req =>
191
187
  req._.req && req._.req.headers && req._.req.headers['x-cds-odata-version'] === 'v2'
192
188
  ? () => {}
@@ -250,12 +246,6 @@ const draftIsLocked = lastChangedAt => {
250
246
  return DRAFT_CANCEL_TIMEOUT_IN_MS > Date.now() - Date.parse(lastChangedAt)
251
247
  }
252
248
 
253
- const getKeyProperty = keys => {
254
- return Object.keys(keys).find(k => {
255
- return k !== 'IsActiveEntity' && !keys[k]._isAssociationStrict
256
- })
257
- }
258
-
259
249
  const filterKeys = keys => {
260
250
  return Object.keys(keys).filter(key => {
261
251
  return key !== 'IsActiveEntity' && !keys[key]._isAssociationStrict
@@ -268,7 +258,6 @@ module.exports = {
268
258
  getUpdateDraftAdminCQN,
269
259
  getEnrichedCQN,
270
260
  removeDraftUUIDIfNecessary,
271
- setStatusCodeAndHeader,
272
261
  isDraftActivateAction,
273
262
  ensureDraftsSuffix,
274
263
  ensureNoDraftsSuffix,
@@ -277,7 +266,6 @@ module.exports = {
277
266
  proxifyToNoDraftsName,
278
267
  addColumnAlias,
279
268
  replaceRefWithDraft,
280
- getKeyProperty,
281
269
  filterKeys,
282
270
  getDeleteDraftAdminCqn,
283
271
  getCompositionTargets
@@ -54,8 +54,6 @@ const _removeIsActiveEntityCondition = where => {
54
54
  i = i + 3
55
55
  } else if (where[i] === 'and' && _isActiveEntity(where[i + 1])) {
56
56
  i = i + 4
57
- } else if (where[i] === 'and' && where[i + 1] === '(' && _isActiveEntity(where[i + 2])) {
58
- i = i + 6
59
57
  } else if (where[i].xpr) {
60
58
  if (where[i].xpr.length) {
61
59
  newWhere.push({ xpr: _removeIsActiveEntityCondition(where[i].xpr) })
@@ -69,8 +67,6 @@ const _removeIsActiveEntityCondition = where => {
69
67
 
70
68
  if (newWhere[0] === 'and' || newWhere[0] === 'or') {
71
69
  newWhere.splice(0, 1)
72
- } else if (newWhere[0] === '(' && newWhere[1] === 'and') {
73
- newWhere.splice(0, 2)
74
70
  }
75
71
 
76
72
  return newWhere
@@ -144,6 +140,7 @@ const removeIsActiveEntityRecursively = where => {
144
140
  entry.xpr = removeIsActiveEntityRecursively(entry.xpr)
145
141
  continue
146
142
  }
143
+
147
144
  if (entry.SELECT && entry.SELECT.where && entry.SELECT.from.ref && !entry.SELECT.from.ref[0].endsWith('_drafts')) {
148
145
  entry.SELECT.where = removeIsActiveEntityRecursively(entry.SELECT.where)
149
146
 
@@ -1,5 +1,6 @@
1
1
  const cds = require('../cds')
2
2
  const LOG = cds.log('hana|db|sql')
3
+ const coloredTxCommands = require('../db/utils/coloredTxCommands')
3
4
 
4
5
  const DatabaseService = require('../db/Service')
5
6
  const pool = require('./pool')
@@ -22,9 +23,10 @@ const _setSessionContext = (dbc, property, value) => {
22
23
  if (dbc._connection) {
23
24
  // Works, but bad practice to access an internal scope
24
25
  dbc._connection.getClientInfo().setProperty(property, value)
25
- } else {
26
- dbc.setClientInfo(property, value)
26
+ return
27
27
  }
28
+
29
+ dbc.setClientInfo(property, value)
28
30
  }
29
31
 
30
32
  /*
@@ -53,7 +55,8 @@ class HanaDatabase extends DatabaseService {
53
55
  /*
54
56
  * tx
55
57
  */
56
- this.on('BEGIN', async function (req) {
58
+ this.on('BEGIN', function () {
59
+ LOG._debug && LOG.debug(coloredTxCommands['BEGIN'])
57
60
  this.dbc.setAutoCommit(false)
58
61
  return 'dummy'
59
62
  })
@@ -62,6 +65,7 @@ class HanaDatabase extends DatabaseService {
62
65
  this.before('COMMIT', this._integrity.performCheck)
63
66
 
64
67
  this.on(['COMMIT', 'ROLLBACK'], function (req) {
68
+ LOG._debug && LOG.debug(coloredTxCommands[req.event])
65
69
  return new Promise((resolve, reject) => {
66
70
  this.dbc[req.event.toLowerCase()](async err => {
67
71
  try {
@@ -70,6 +74,7 @@ class HanaDatabase extends DatabaseService {
70
74
  // REVISIT: what to do?
71
75
  return reject(e)
72
76
  }
77
+
73
78
  if (err) return reject(err)
74
79
  resolve('dummy')
75
80
  })
@@ -121,21 +126,24 @@ class HanaDatabase extends DatabaseService {
121
126
  // eslint-disable-next-line complexity
122
127
  async acquire(arg) {
123
128
  // REVISIT: remove fallback arg.user.tenant with cds^6 (still needed for cds-mtx)
124
- const tenant = (typeof arg === 'string' ? arg : arg.tenant || (arg.user && arg.user.tenant)) || 'anonymous'
129
+ const tenant = arg && (typeof arg === 'string' ? arg : arg.tenant || (arg.user && arg.user.tenant))
125
130
  const dbc = await pool.acquire(tenant, this)
126
131
 
127
- if (typeof arg !== 'string') {
132
+ if (arg && typeof arg !== 'string') {
128
133
  _setSessionContext(dbc, 'APPLICATIONUSER', arg.user.id || 'ANONYMOUS')
129
134
  _setSessionContext(dbc, 'LOCALE', arg.locale || 'en')
135
+
130
136
  // REVISIT: stable access
131
137
  const validFrom = (arg.context && arg.context._ && arg.context._['VALID-FROM']) || (arg._ && arg._['VALID-FROM'])
132
138
  const validto = (arg.context && arg.context._ && arg.context._['VALID-TO']) || (arg._ && arg._['VALID-TO'])
139
+
133
140
  if (validFrom)
134
141
  _setSessionContext(
135
142
  dbc,
136
143
  'VALID-FROM',
137
144
  validFrom instanceof Date ? validFrom.toISOString().replace('T', ' ') : validFrom.replace('T', ' ')
138
145
  )
146
+
139
147
  if (validto)
140
148
  _setSessionContext(
141
149
  dbc,
@@ -145,12 +153,12 @@ class HanaDatabase extends DatabaseService {
145
153
  }
146
154
 
147
155
  dbc._tenant = tenant
148
-
149
156
  return dbc
150
157
  }
151
158
 
152
159
  release(dbc) {
153
160
  if (dbc) return pool.release(dbc)
161
+
154
162
  // should not happen, but just in case
155
163
  LOG._warn && LOG.warn(new Error('Release called without client. Please report this warning.'))
156
164
  }
@@ -158,7 +166,6 @@ class HanaDatabase extends DatabaseService {
158
166
  // REVISIT: should happen automatically after a configurable time
159
167
  // poolOnly: private param for mtx
160
168
  async disconnect(tenant, poolOnly) {
161
- tenant = tenant || 'anonymous'
162
169
  await pool.drain(tenant)
163
170
  if (!poolOnly) super.disconnect(tenant)
164
171
  }
@@ -79,7 +79,7 @@ if (cds.env.sql.names === 'plain') {
79
79
  CustomSelectBuilder.prototype._buildRefElement = function (col, res, noQuoting) {
80
80
  res = new this.ReferenceBuilder(col, this._options, this._csn).build()
81
81
 
82
- if (!noQuoting && !col.as && res.sql && !res.sql.match(/\sas\s/i)) {
82
+ if (!noQuoting && !col.as) {
83
83
  res.sql += ` AS ${this._options.delimiter}${col.ref[col.ref.length - 1]}${this._options.delimiter}`
84
84
  }
85
85
 
@@ -65,7 +65,7 @@ const _preparedStmtUsingDynatrace = function (client, prepareFn, dbInfo) {
65
65
 
66
66
  const dynatraceClient = (client, credentials, tenant) => {
67
67
  const dbInfo = {
68
- name: `SAPHANA${tenant === 'anonymous' ? '' : `-${tenant}`}`,
68
+ name: `SAPHANA${tenant ? `-${tenant}` : ''}`,
69
69
  vendor: dynatrace.sdk.DatabaseVendor.HANADB,
70
70
  host: credentials.host,
71
71
  port: Number(credentials.port)
@@ -90,7 +90,7 @@ const _createHanaClientStreamingStatement = function (extension, createStmtFn) {
90
90
  // args = [sql, options, callback] --> options is optional
91
91
  return function (dbc, sql, cb) {
92
92
  const dbInfo = {
93
- name: `SAPHANA${dbc._tenant === 'anonymous' ? '' : `-${dbc._tenant}`}`,
93
+ name: `SAPHANA${dbc._tenant ? `-${dbc._tenant}` : ''}`,
94
94
  vendor: dynatrace.sdk.DatabaseVendor.HANADB,
95
95
  host: dbc._creds.host,
96
96
  port: Number(dbc._creds.port)
@@ -1,14 +1,13 @@
1
1
  const { ensureUnlocalized } = require('../common/utils/draft')
2
2
  const { redirect } = require('../db/utils/localized')
3
3
 
4
- const getLocalize = (locale, model) => name => {
4
+ const getLocalize = model => name => {
5
5
  if (name.endsWith('_drafts')) return name
6
6
 
7
- // if we get here via onReadDraft, target is already localized
8
- // because of subrequest using SELECT.from as new target
7
+ // if we get here via onReadDraft, the target is already localized
8
+ // because of sub-request using SELECT.from as the new target
9
9
  const target = model.definitions[ensureUnlocalized(name)]
10
10
  const localizedView = target && target['@cds.localized'] !== false && model.definitions[`localized.${name}`]
11
-
12
11
  return localizedView ? localizedView.name : name
13
12
  }
14
13
 
@@ -28,10 +27,12 @@ const localizedHandler = function (req) {
28
27
  const columns = query.SELECT.columns
29
28
  if (columns && columns.length === 1 && columns[0].func === 'count') return
30
29
 
31
- // suppress localization in "select for update"
30
+ // suppress localization (no redirection to localized view) for queries that
31
+ // lock the selected record (exclusive and shared locks)
32
32
  if (query.SELECT.forUpdate) return
33
+ if (query.SELECT.forShareLock) return
33
34
 
34
- redirect(query, getLocalize(req.locale, this.model))
35
+ redirect(query, getLocalize(this.model))
35
36
  }
36
37
 
37
38
  localizedHandler._initial = true
@@ -5,6 +5,7 @@ const { pool } = require('@sap/cds-foss')
5
5
  const hana = require('./driver')
6
6
 
7
7
  const _require = require('../common/utils/require')
8
+ const getError = require('../common/error')
8
9
 
9
10
  function multiTenantInstanceManager(config = cds.env.requires.db) {
10
11
  const { credentials } = config
@@ -65,7 +66,7 @@ function singleTenantInstanceManager(config = cds.env.requires.db) {
65
66
  async function credentials4(tenant, db) {
66
67
  if (!db._instance_manager) {
67
68
  const opts = db.options && db.options.credentials ? db.options : undefined
68
- db._instance_manager = cds.env.requires.db.multiTenant
69
+ db._instance_manager = cds.requires.multitenancy
69
70
  ? await multiTenantInstanceManager(opts)
70
71
  : singleTenantInstanceManager(opts)
71
72
  }
@@ -221,12 +222,14 @@ async function resilientAcquire(pool, attempts = 1) {
221
222
  }
222
223
  }
223
224
  if (client) return client
224
- err.statusCode = 503
225
- err.message =
226
- 'Acquiring client from pool timed out. Please review your system setup, transaction handling, and pool configuration.'
227
- err._attempts = attempt
228
225
  const { borrowed, pending, size, available, max } = pool
229
- err._poolState = { borrowed, pending, size, available, max }
226
+ err = getError(
227
+ Object.assign(err, {
228
+ statusCode: 503,
229
+ message: `Acquiring client from pool timed out. Please review your system setup, transaction handling, and pool configuration. Pool State: borrowed: ${borrowed}, pending: ${pending}, size: ${size}, available: ${available}, max: ${max}`
230
+ })
231
+ )
232
+ err._attempts = attempt
230
233
  LOG._debug && LOG.debug(err)
231
234
  throw err
232
235
  }
@@ -11,9 +11,8 @@ function searchHandler(req) {
11
11
  // REVISIT: remove feature toggle optimized_search after grace period
12
12
  // inject the search2cqn4sql module into the rewrite handler only when
13
13
  // the optimized search feature toggle is turned on
14
- if (cds.env.features.optimized_search) {
15
- _setSearchOptions(req.query, { search2cqn4sql, locale: req.locale })
16
- }
14
+ if (cds.env.features.optimized_search === false) return
15
+ _setSearchOptions(req.query, { search2cqn4sql, locale: req.locale })
17
16
  }
18
17
 
19
18
  // handlers marked with `._initial = true` run in sequence
@@ -24,7 +24,7 @@
24
24
  * @param {import("../types/api").ColumnRefs} columns The columns to be searched
25
25
  * @returns {import("../types/api").searchContainsExp} The `CONTAINS` CQN expression
26
26
  */
27
- const searchToContains = (cqnSearchPhrase, columns) => {
27
+ const search2Contains = (cqnSearchPhrase, columns) => {
28
28
  // serialize the CQN search phrase
29
29
  const searchString = cqnSearchPhrase.reduce((searchStringAccumulator, currentValue) => {
30
30
  // Multiple search terms separated by an space are automatically
@@ -92,4 +92,7 @@ const isContainsPredicateSupported = query => {
92
92
  return true
93
93
  }
94
94
 
95
- module.exports = { searchToContains, isContainsPredicateSupported }
95
+ module.exports = {
96
+ isContainsPredicateSupported,
97
+ search2Contains
98
+ }
@@ -1,6 +1,6 @@
1
1
  const { computeColumnsToBeSearched } = require('../cds-services/services/utils/columns')
2
2
  const searchToLike = require('../common/utils/searchToLike')
3
- const { isContainsPredicateSupported, searchToContains } = require('./searchToContains')
3
+ const { isContainsPredicateSupported, search2Contains } = require('./search2Contains')
4
4
  const { addAliasToExpression } = require('../db/utils/generateAliases')
5
5
 
6
6
  /**
@@ -24,7 +24,7 @@ const search2cqn4sql = (query, entity, options) => {
24
24
  const cqnSearchPhrase = query.SELECT.search
25
25
  if (!cqnSearchPhrase) return query
26
26
 
27
- let { columns: columnsToBeSearched = computeColumnsToBeSearched(query, entity), locale } = options
27
+ let { columns: columns2Search = computeColumnsToBeSearched(query, entity), locale } = options
28
28
  const localizedAssociation = _getLocalizedAssociation(entity)
29
29
 
30
30
  // If the localized association is defined for the target entity,
@@ -34,14 +34,15 @@ const search2cqn4sql = (query, entity, options) => {
34
34
  // suppress the localize handler from redirecting the query's target to the localized view
35
35
  Object.defineProperty(query, '_suppressLocalization', { value: true })
36
36
 
37
+ const columnsDefs = entity.query && entity.query.SELECT.columns
38
+ const isSomeColumn2SearchUseFunction = _isSomeColumn2SearchAFunction(columns2Search, columnsDefs)
39
+
37
40
  if (resolveLocalizedDataAtRuntime) {
38
41
  const onCondition = entity._relations[localizedAssociation.name].join(localizedAssociation.target, entity.name)
39
42
 
40
43
  // REVISIT this is dirty but works for now
41
44
  // replace $user_locale placeholder with the user locale or the HANA session context
42
- if (onCondition[0].xpr) {
43
- onCondition[0].xpr[onCondition[0].xpr.length - 1] = { val: locale || "SESSION_CONTEXT('LOCALE')" }
44
- } else onCondition[onCondition.length - 2] = { val: locale || "SESSION_CONTEXT('LOCALE')" }
45
+ onCondition[0].xpr[onCondition[0].xpr.length - 1] = { val: locale || "SESSION_CONTEXT('LOCALE')" }
45
46
 
46
47
  // inner join the target table with the _texts table (the _texts table contains
47
48
  // the translated texts)
@@ -49,25 +50,18 @@ const search2cqn4sql = (query, entity, options) => {
49
50
  query.join(localizedEntityName).on(onCondition)
50
51
 
51
52
  // prevent SQL ambiguity error for columns with the same name
52
- columnsToBeSearched = _addAliasToQuery(query, entity, columnsToBeSearched)
53
+ columns2Search = _addAliasToQuery(query, entity, columns2Search)
53
54
  } // else --> resolve localized texts via localized view (default)
54
55
 
55
- const useContains = isContainsPredicateSupported(query)
56
+ const useContains = !isSomeColumn2SearchUseFunction && isContainsPredicateSupported(query)
56
57
  let expression
57
58
 
58
59
  if (useContains) {
59
- const namedColumns = columnsToBeSearched.filter(col => !col.func)
60
- expression = searchToContains(cqnSearchPhrase, namedColumns)
61
-
62
- // func columns handling
63
- if (columnsToBeSearched.length > namedColumns.length) {
64
- const funcColumns = columnsToBeSearched.filter(col => col.func)
65
- expression = [expression, 'or', ...searchToLike(cqnSearchPhrase, funcColumns)]
66
- }
60
+ expression = search2Contains(cqnSearchPhrase, columns2Search)
67
61
  } else {
68
62
  // No CONTAINS optimization possible. The search implementation for localized
69
63
  // texts falls back to the LIKE predicate.
70
- expression = searchToLike(cqnSearchPhrase, columnsToBeSearched)
64
+ expression = searchToLike(cqnSearchPhrase, columns2Search)
71
65
  }
72
66
 
73
67
  // REVISIT: find out here if where or having must be used
@@ -75,7 +69,16 @@ const search2cqn4sql = (query, entity, options) => {
75
69
  return query
76
70
  }
77
71
 
78
- const _getLocalizedAssociation = entity => entity.associations && entity.associations.localized
72
+ const _isSomeColumn2SearchAFunction = (columns2Search, columnsDefs) =>
73
+ columns2Search.some(column2Search => {
74
+ if (column2Search.func) return true
75
+ return columnsDefs && columnsDefs.some(columnDef => columnDef.func && columnDef.as === column2Search.ref[0])
76
+ })
77
+
78
+ const _getLocalizedAssociation = entity => {
79
+ const associations = entity.associations
80
+ return associations && associations.localized
81
+ }
79
82
 
80
83
  // The inner join modifies the original SELECT ... FROM query and adds ambiguity,
81
84
  // therefore add the table/entity name (as a preceding element) to the columns ref
@@ -5,12 +5,8 @@ module.exports = {
5
5
  return this._odatav4 || (this._odatav4 = require('./cds-services/adapter/odata-v4/to'))
6
6
  },
7
7
 
8
- get old_rest() {
9
- return this._old_rest || (this._old_rest = require('./cds-services/adapter/rest/to'))
10
- },
11
-
12
- get new_rest() {
13
- return this._new_rest || (this._new_rest = require('../rest'))
8
+ get rest() {
9
+ return this._rest || (this._rest = require('../rest'))
14
10
  }
15
11
  },
16
12
 
@@ -1,8 +1,8 @@
1
1
  const cds = require('../cds')
2
2
  const MessagingService = require('./service.js')
3
- const { queueName } = require('./common-utils/naming-conventions')
4
3
  const optionsApp = require('../common/utils/vcap.js')
5
4
  const normalizeIncomingMessage = require('./common-utils/normalizeIncomingMessage')
5
+ const appId = require('./common-utils/appId')
6
6
 
7
7
  class AMQPWebhookMessaging extends MessagingService {
8
8
  async init() {
@@ -12,7 +12,10 @@ class AMQPWebhookMessaging extends MessagingService {
12
12
  delete queueConfig.name
13
13
  if (Object.keys(queueConfig).length) this.queueConfig = queueConfig
14
14
  }
15
- this.queueName = queueName(this.options, this.optionsApp)
15
+ this.queueName = this.prepareQueueName(
16
+ (this.options.queue && this.options.queue.name) ||
17
+ (this.options.credentials && this.options.credentials.namespace ? '$namespace/$appId' : '$appId')
18
+ )
16
19
 
17
20
  cds.once('listening', () => {
18
21
  this.startListening()
@@ -28,27 +31,32 @@ class AMQPWebhookMessaging extends MessagingService {
28
31
  return client.emit(_msg)
29
32
  }
30
33
 
34
+ prepareQueueName(queueName) {
35
+ const queue = queueName.replace(/\$appId/g, appId())
36
+ const namespace = (this.options.credentials && this.options.credentials.namespace) || ''
37
+ return queue.replace(/\$namespace/g, namespace)
38
+ }
39
+
31
40
  startListening(opt = {}) {
32
- if (this.subscribedTopics.size) {
33
- const management = this.getManagement()
34
- if (!opt.doNotDeploy) this.queued(management.createQueueAndSubscriptions.bind(management))()
35
- this.queued(this.listenToClient.bind(this))(async (_topic, _payload, _other, { done, failed }) => {
36
- const msg = Object.assign(normalizeIncomingMessage(_payload), _other || {})
37
- msg.event = _topic
38
-
39
- if (!msg._) msg._ = {}
40
- msg._.topic = _topic
41
- try {
42
- await super.emit(msg)
43
- done()
44
- } catch (e) {
45
- // In case of AMQP and Solace, the `failed` callback must be called
46
- // with an error, otherwise there are problems with the redelivery count.
47
- failed(new Error('processing failed'))
48
- this.LOG.error('ERROR occured in asynchronous event processing:', e)
49
- }
50
- })
51
- }
41
+ if (!this.subscribedTopics.size) return
42
+ const management = this.getManagement()
43
+ if (!opt.doNotDeploy) this.queued(management.createQueueAndSubscriptions.bind(management))()
44
+ this.queued(this.listenToClient.bind(this))(async (_topic, _payload, _other, { done, failed }) => {
45
+ const msg = Object.assign(normalizeIncomingMessage(_payload), _other || {})
46
+ msg.event = _topic
47
+
48
+ if (!msg._) msg._ = {}
49
+ msg._.topic = _topic
50
+ try {
51
+ await super.emit(msg)
52
+ done()
53
+ } catch (e) {
54
+ // In case of AMQP and Solace, the `failed` callback must be called
55
+ // with an error, otherwise there are problems with the redelivery count.
56
+ failed(new Error('processing failed'))
57
+ this.LOG.error('ERROR occured in asynchronous event processing:', e)
58
+ }
59
+ })
52
60
  }
53
61
 
54
62
  listenToClient(cb) {
@@ -4,7 +4,7 @@ const { connect, disconnect } = require('./connections')
4
4
  const { hasPersistentOutbox } = require('../outbox/utils')
5
5
 
6
6
  const addDataListener = (client, queue, prefix, cb) =>
7
- new Promise((resolve, reject) => {
7
+ new Promise(resolve => {
8
8
  const source = `${prefix}${queue}`
9
9
  client
10
10
  .receiver(queue)
@@ -53,13 +53,14 @@ class AMQPClient {
53
53
  this.prefix = prefix
54
54
  this.keepAlive = keepAlive
55
55
  this.service = service
56
+ cds.on('shutdown', () => this.disconnect())
56
57
  }
57
58
 
58
- connect() {
59
+ async connect() {
59
60
  this.client = new ClientAmqp(this.optionsAMQP)
60
61
  this.sender = sender(this.client, this.service.optionsApp)
61
62
  this.stream = this.sender.attach('')
62
- return connect(this.client, this.service.LOG, this.keepAlive)
63
+ await connect(this.client, this.service.LOG, this.keepAlive)
63
64
  }
64
65
 
65
66
  async disconnect() {
@@ -0,0 +1,9 @@
1
+ const optionsApp = require('../../common/utils/vcap')
2
+ const appId = () => {
3
+ const appName = optionsApp.appName || 'CAP'
4
+ const appID = optionsApp.appID || '00000000'
5
+ const shrunkAppID = appID.substring(0, 4)
6
+ return `${appName}/${shrunkAppID}`
7
+ }
8
+
9
+ module.exports = appId
@@ -1,20 +1,7 @@
1
1
  const https = require('https')
2
2
  const requestToken = require('../http-utils/token')
3
3
 
4
- const authorizedRequest = ({
5
- method,
6
- uri,
7
- path,
8
- oa2,
9
- tenant,
10
- dataObj,
11
- headers,
12
- tokenStore,
13
- attemptInfo,
14
- errMsg,
15
- target
16
- }) => {
17
- attemptInfo()
4
+ const authorizedRequest = ({ method, uri, path, oa2, tenant, dataObj, headers, tokenStore }) => {
18
5
  return new Promise((resolve, reject) => {
19
6
  ;((tokenStore.token && Promise.resolve(tokenStore.token)) || requestToken(oa2, tenant, tokenStore))
20
7
  .catch(err => reject(err))
@@ -56,10 +43,7 @@ const authorizedRequest = ({
56
43
  }
57
44
  const result = { body, headers: res.headers, statusCode: res.statusCode }
58
45
  if (res.statusCode < 200 || (res.statusCode >= 300 && !(res.statusCode === 404 && method === 'DELETE'))) {
59
- const errObj = new Error(errMsg)
60
- errObj.target = target
61
- errObj.response = result
62
- reject(errObj)
46
+ reject(result)
63
47
  } else {
64
48
  resolve(result)
65
49
  }
@@ -7,7 +7,7 @@ const _connectUntilConnected = (client, LOG, x) => {
7
7
  .then(() => {
8
8
  LOG._warn && LOG.warn('Reconnected to Enterprise Messaging Client')
9
9
  })
10
- .catch(e => {
10
+ .catch(() => {
11
11
  LOG._warn &&
12
12
  LOG.warn(
13
13
  `Connection to Enterprise Messaging Client lost: Reconnecting in ${Math.round(_waitingTime / 1000)} s`
@@ -1,6 +1,6 @@
1
1
  const AMQPWebhookMessaging = require('./AMQPWebhookMessaging')
2
2
  const AMQPClient = require('./common-utils/AMQPClient')
3
- const optionsMessaging = require('./enterprise-messaging-utils/options-messaging.js')
3
+ const { optionsMessagingAMQP } = require('./enterprise-messaging-utils/options-messaging.js')
4
4
  const optionsManagement = require('./enterprise-messaging-utils/options-management.js')
5
5
  const EMManagement = require('./enterprise-messaging-utils/EMManagement.js')
6
6
  const cloudEvents = require('./enterprise-messaging-utils/cloudEvents.js')
@@ -14,7 +14,7 @@ class EnterpriseMessagingShared extends AMQPWebhookMessaging {
14
14
 
15
15
  getClient() {
16
16
  if (this.client) return this.client
17
- const optionsAMQP = optionsMessaging(this.options, 'amqp10ws')
17
+ const optionsAMQP = optionsMessagingAMQP(this.options)
18
18
  this.client = new AMQPClient({
19
19
  optionsAMQP,
20
20
  prefix: { topic: 'topic:', queue: 'queue:' },