@sap/cds 5.9.6 → 6.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (381) hide show
  1. package/CHANGELOG.md +266 -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 +90 -53
  25. package/bin/build/provider/mtx/resourcesTarBuilder.js +68 -0
  26. package/bin/build/provider/mtx-sidecar/index.js +80 -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 +19 -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 +9 -10
  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 +56 -21
  37. package/bin/utils/log.js +13 -30
  38. package/bin/version.js +5 -4
  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 +11 -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 +70 -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 +23 -20
  86. package/lib/serve/index.js +51 -54
  87. package/lib/utils/axios.js +8 -12
  88. package/lib/utils/index.js +3 -3
  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 +128 -42
  106. package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +6 -3
  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 +10 -45
  109. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +5 -9
  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 +1 -1
  114. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +15 -21
  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 +100 -91
  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 +77 -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 +16 -18
  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 +15 -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 +11 -4
  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 +6 -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 +3 -7
  232. package/libx/_runtime/fiori/generic/index.js +31 -0
  233. package/libx/_runtime/fiori/generic/new.js +2 -4
  234. package/libx/_runtime/fiori/generic/patch.js +4 -8
  235. package/libx/_runtime/fiori/generic/prepare.js +2 -4
  236. package/libx/_runtime/fiori/generic/read.js +137 -162
  237. package/libx/_runtime/fiori/generic/readOverDraft.js +10 -4
  238. package/libx/_runtime/fiori/utils/handler.js +10 -5
  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 +11 -2
  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 +2 -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 +84 -46
  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 +261 -157
  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
@@ -24,6 +24,7 @@ const _findSubselect = where => {
24
24
  if (e.xpr) {
25
25
  return _findSubselect(e.xpr)
26
26
  }
27
+
27
28
  return e.SELECT && where[i - 1] === 'exists'
28
29
  })
29
30
  }
@@ -33,29 +34,16 @@ const _findRootSubSelectFor = query => {
33
34
  const subSelect = _findSubselect(query.SELECT.where)
34
35
  return subSelect ? _findRootSubSelectFor(subSelect) : query
35
36
  }
37
+
36
38
  return query
37
39
  }
38
40
 
39
41
  // append where with clauses from @restrict
40
- const _getWhereWithAppendedDraftRestrictions = (where = [], req, scenarioAlias, model) => {
42
+ const _getWhereWithAppendedDraftRestrictions = (where = [], req) => {
41
43
  if (req.query._draftRestrictions) {
42
44
  for (const each of req.query._draftRestrictions) {
43
45
  const xpr = each._xpr
44
46
  if (each.target.name === ensureUnlocalized(req.target.name)) {
45
- // > restriction directly on child
46
- // REVISIT: remove support for selects in restriction with cds^6
47
- // adjust alias of @restrict where "exists (select ...)"
48
- if (scenarioAlias && model)
49
- xpr
50
- .filter(e => e.SELECT && e.SELECT.from && e.SELECT.where)
51
- .forEach(e => {
52
- const entity = model.definitions[e.SELECT.from.ref[0]]
53
- e.SELECT.where = e.SELECT.where.map(w => {
54
- if (w.ref && w.ref.length === 1 && !entity.elements[w.ref[0]]) w.ref.unshift(scenarioAlias)
55
- return w
56
- })
57
- })
58
-
59
47
  if (where.length) where.push('and')
60
48
  // restriction might contain or clause -> use xpr for grouping
61
49
  xpr.includes('or') ? where.push({ xpr }) : where.push(...xpr)
@@ -76,13 +64,12 @@ const _getWhereWithAppendedDraftRestrictions = (where = [], req, scenarioAlias,
76
64
  }
77
65
  }
78
66
  }
67
+
79
68
  return where
80
69
  }
81
70
 
82
71
  const _isTrue = val => val === true || val === 'true'
83
-
84
72
  const _isFalse = val => val === false || val === 'false'
85
-
86
73
  const _inProcessByUserWhere = userId => [{ ref: ['filterAdmin', 'InProcessByUser'] }, '=', { val: userId }]
87
74
 
88
75
  const _getTableName = (
@@ -162,7 +149,6 @@ const _getDefaultDraftProperties = ({ hasDraft, isActive = true, withDraftUUID =
162
149
  // draft values for active entities with calculated hasDraft property
163
150
  const _getDraftPropertiesDetermineDraft = (req, where, tableName, calcDraftUUID = false) => {
164
151
  const { table } = _getTableName(req, true)
165
-
166
152
  tableName = tableName || table
167
153
 
168
154
  const hasDraftQuery = SELECT.from(tableName, [{ val: 1 }])
@@ -209,18 +195,18 @@ function _copyCQNPartial(partial) {
209
195
  return newPartial
210
196
  }
211
197
 
212
- return partial.ref ? Object.assign({}, partial, { ref: _copyArray(partial.ref) }) : Object.assign({}, partial)
198
+ if (partial.ref) {
199
+ return Object.assign({}, partial, { ref: _copyArray(partial.ref) })
200
+ }
201
+
202
+ return Object.assign({}, partial)
213
203
  }
214
204
 
215
205
  function _copyArray(array) {
216
- return array.map(entry => {
217
- return typeof entry === 'object' && !(entry instanceof String) ? _copyCQNPartial(entry) : entry
218
- })
206
+ return array.map(entry => (typeof entry === 'object' && !(entry instanceof String) ? _copyCQNPartial(entry) : entry))
219
207
  }
220
208
 
221
- const _isValidDraftOfWhichIAmOwner = isActiveEntity => {
222
- return isActiveEntity.op === '=' && _isFalse(isActiveEntity.value.val)
223
- }
209
+ const _isValidDraftOfWhichIAmOwner = isActiveEntity => isActiveEntity.op === '=' && _isFalse(isActiveEntity.value.val)
224
210
 
225
211
  const _isValidActiveWithoutDraft = (isActiveEntity, hasDraftEntity) => {
226
212
  return (
@@ -293,7 +279,7 @@ const _getOuterMostColumns = (columnsFromRequest, additionalDraftColumns) => {
293
279
  // adds base columns 'InProcessByUser' and 'CreatedByUser' to columns param if needed
294
280
  // those are required for calculating 'DraftIsProcessedByMe' and 'DraftIsCreatedByMe'
295
281
  const _ensureDraftAdminColumnsForCalculation = columns => {
296
- columns.forEach((c, i) => {
282
+ columns.forEach(c => {
297
283
  if (c.ref && c.ref[0] === 'DraftIsCreatedByMe' && !columns.find(e => e.ref && e.ref[0] === 'CreatedByUser')) {
298
284
  columns.push({ ref: ['CreatedByUser'] })
299
285
  } else if (
@@ -337,13 +323,7 @@ const _allInactive = (req, columns) => {
337
323
  // ensure only own drafts are read
338
324
  const cqn = SELECT.from(table)
339
325
  .join('DRAFT.DraftAdministrativeData', 'filterAdmin')
340
- .on([
341
- { ref: [table.as, 'DraftAdministrativeData_DraftUUID'] },
342
- '=',
343
- {
344
- ref: ['filterAdmin', 'DraftUUID']
345
- }
346
- ])
326
+ .on([{ ref: [table.as, 'DraftAdministrativeData_DraftUUID'] }, '=', { ref: ['filterAdmin', 'DraftUUID'] }])
347
327
  .where(_inProcessByUserWhere(req.user.id))
348
328
 
349
329
  if (isCount) {
@@ -353,7 +333,6 @@ const _allInactive = (req, columns) => {
353
333
  }
354
334
 
355
335
  cqn.where(req.query.SELECT.where)
356
-
357
336
  return { cqn: getEnrichedCQN(cqn, req.query.SELECT, []), scenario: SCENARIO.ALL_INACTIVE }
358
337
  }
359
338
 
@@ -377,22 +356,7 @@ const _buildWhere = (where, table) => {
377
356
  }
378
357
  }
379
358
 
380
- const _buildOrderBy = (query, columns, table) => {
381
- for (const entry of query.SELECT.orderBy || []) {
382
- // detect if calculated value
383
- if (entry.ref && columns.some(c => c.as === entry.ref[entry.ref.length - 1])) {
384
- // remove table alias if present
385
- if (entry.ref[0] === table.as) {
386
- entry.ref.splice(0, 1)
387
- }
388
- } else if (table.as && entry.ref[0] !== table.as) {
389
- // if regular column and no alias present, add it
390
- entry.ref.unshift(table.as)
391
- }
392
- }
393
- }
394
-
395
- const _allActive = (req, columns, model) => {
359
+ const _allActive = (req, columns) => {
396
360
  const { table } = _getTableName(req)
397
361
  if (!table.as) {
398
362
  table.as = 'active'
@@ -405,7 +369,6 @@ const _allActive = (req, columns, model) => {
405
369
 
406
370
  const ids = filterKeys(req.target.keys)
407
371
  const isCount = columns.some(element => element.func === 'count')
408
-
409
372
  const xpr = {
410
373
  xpr: [
411
374
  'case',
@@ -437,15 +400,12 @@ const _allActive = (req, columns, model) => {
437
400
  }
438
401
 
439
402
  const scenarioAlias = 'active'
440
-
441
- req.query.SELECT.where = _getWhereWithAppendedDraftRestrictions(req.query.SELECT.where, req, scenarioAlias, model)
403
+ req.query.SELECT.where = _getWhereWithAppendedDraftRestrictions(req.query.SELECT.where, req)
442
404
 
443
405
  if (req.query.SELECT.where) {
444
406
  _buildWhere(req.query.SELECT.where, table)
445
407
  }
446
408
 
447
- _buildOrderBy(req.query, cqn.SELECT.columns, table)
448
-
449
409
  return {
450
410
  cqn: getEnrichedCQN(cqn, req.query.SELECT, req.query.SELECT.where, scenarioAlias),
451
411
  scenario: SCENARIO.ALL_ACTIVE
@@ -472,31 +432,22 @@ const _activeWithoutDraft = (req, draftWhere, columns) => {
472
432
  )
473
433
 
474
434
  const outerMostColumns = _getOuterMostColumns(columns, _getDefaultDraftProperties({ hasDraft: false }))
475
-
476
435
  const cqn = SELECT.from(active.table)
477
436
  .columns(...outerMostColumns)
478
437
  .where(['not exists', subSelect])
479
438
 
480
439
  draftWhere = _getWhereWithAppendedDraftRestrictions(draftWhere, req)
481
-
482
440
  return { cqn: getEnrichedCQN(cqn, req.query.SELECT, draftWhere), scenario: SCENARIO.ACTIVE_WITHOUT_DRAFT }
483
441
  }
484
442
 
485
443
  const _draftOfWhichIAmOwner = (req, draftWhere, columns) => {
486
444
  const { table, name } = _getTableName(req, true)
487
-
488
445
  const outerMostColumns = _getOuterMostColumns(addColumnAlias(columns, name), DRAFT_COLUMNS_CASTED)
489
446
 
490
447
  const cqn = SELECT.from(table)
491
448
  .columns(...outerMostColumns)
492
449
  .join('DRAFT.DraftAdministrativeData', 'filterAdmin')
493
- .on([
494
- { ref: [name, 'DraftAdministrativeData_DraftUUID'] },
495
- '=',
496
- {
497
- ref: ['filterAdmin', 'DraftUUID']
498
- }
499
- ])
450
+ .on([{ ref: [name, 'DraftAdministrativeData_DraftUUID'] }, '=', { ref: ['filterAdmin', 'DraftUUID'] }])
500
451
  .where(_inProcessByUserWhere(req.user.id))
501
452
 
502
453
  return { cqn: getEnrichedCQN(cqn, req.query.SELECT, draftWhere), scenario: SCENARIO.DRAFT_WHICH_OWNER }
@@ -512,13 +463,7 @@ const _activeWithDraftInProcess = (req, draftWhere, columns, isLocked) => {
512
463
  let subSelect = SELECT.from(draftName)
513
464
  .columns(...keys)
514
465
  .join('DRAFT.DraftAdministrativeData', 'filterAdmin')
515
- .on([
516
- { ref: [draftName, 'DraftAdministrativeData_DraftUUID'] },
517
- '=',
518
- {
519
- ref: ['filterAdmin', 'DraftUUID']
520
- }
521
- ])
466
+ .on([{ ref: [draftName, 'DraftAdministrativeData_DraftUUID'] }, '=', { ref: ['filterAdmin', 'DraftUUID'] }])
522
467
 
523
468
  const DRAFT_CANCEL_TIMEOUT_IN_SEC = ((cds.env.drafts && cds.env.drafts.cancellationTimeout) || 15) * 60
524
469
 
@@ -530,25 +475,20 @@ const _activeWithDraftInProcess = (req, draftWhere, columns, isLocked) => {
530
475
  { ref: ['filterAdmin', 'InProcessByUser'] },
531
476
  'is not null',
532
477
  'and',
533
- {
534
- func: 'seconds_between',
535
- args: [{ ref: ['filterAdmin', 'LastChangeDateTime'] }, 'CURRENT_TIMESTAMP']
536
- },
478
+ { func: 'seconds_between', args: [{ ref: ['filterAdmin', 'LastChangeDateTime'] }, 'CURRENT_TIMESTAMP'] },
537
479
  isLocked ? '<' : '>',
538
480
  { val: DRAFT_CANCEL_TIMEOUT_IN_SEC }
539
481
  ])
540
482
 
541
483
  subSelect = keys.reduce(
542
- (select, key) => subSelect.where([{ ref: [active.name, key] }, '=', { ref: [draftName, key] }]),
484
+ (_select, key) => subSelect.where([{ ref: [active.name, key] }, '=', { ref: [draftName, key] }]),
543
485
  subSelect
544
486
  )
545
487
 
546
488
  const outerMostColumns = _getOuterMostColumns(columns, draftColumns)
547
-
548
489
  const cqn = SELECT.from(active.table).columns(outerMostColumns)
549
490
  cqn.where(_getWhereWithAppendedDraftRestrictions([], req))
550
491
  cqn.where(['exists', subSelect])
551
-
552
492
  return { cqn: getEnrichedCQN(cqn, req.query.SELECT, draftWhere), scenario: SCENARIO.DRAFT_IN_PROCESS }
553
493
  }
554
494
 
@@ -572,10 +512,12 @@ const _joinFromWhere = (where, parentAlias, targetAlias) => {
572
512
  return where.reduce((links, el, idx, where) => {
573
513
  if (el.xpr) {
574
514
  const result = _joinFromWhere(el.xpr, parentAlias, targetAlias)
515
+
575
516
  if (result.length) {
576
517
  if (links.length) links.push('and')
577
518
  links.push(...result)
578
519
  }
520
+
579
521
  return links
580
522
  }
581
523
 
@@ -584,11 +526,13 @@ const _joinFromWhere = (where, parentAlias, targetAlias) => {
584
526
  if (links.length) links.push('and')
585
527
  links.push(el, '=', where[idx - 2])
586
528
  }
529
+
587
530
  if (where[idx + 1] && where[idx + 1] === '=' && isTargetRef(where[idx + 2], targetAlias)) {
588
531
  if (links.length) links.push('and')
589
532
  links.push(el, '=', where[idx + 2])
590
533
  }
591
534
  }
535
+
592
536
  return links
593
537
  }, [])
594
538
  }
@@ -609,6 +553,7 @@ const _functionContainsDraftField = obj =>
609
553
  })
610
554
 
611
555
  const _isLogicalFunction = (where, index) => {
556
+ // REVISIT
612
557
  const borders = ['(', ')', 'and', 'or', undefined]
613
558
 
614
559
  return borders.includes(where[index - 1]) && borders.includes(where[index + 1])
@@ -621,6 +566,7 @@ const _getWhereForActive = where => {
621
566
  activeWhere.push({ xpr: _getWhereForActive(where[i].xpr) })
622
567
  continue
623
568
  }
569
+
624
570
  if (_isDraftField(where[i])) {
625
571
  activeWhere.push({ val: null })
626
572
  } else if (_functionContainsDraftField(where[i])) {
@@ -666,9 +612,10 @@ const _siblingEntity = (
666
612
  const subScenario = _siblingSubScenario(nav, siblingIndex, siblingQuery, target, params, model, onCond, req)
667
613
  const isSiblingDraft = subScenario
668
614
  ? subScenario.isSiblingActive || subScenario.scenario === 'ACTIVE' || subScenario.scenario === 'ALL_ACTIVE'
669
- : keys.IsActiveEntity && keys.IsActiveEntity !== 'false'
615
+ : keys.IsActiveEntity && keys.IsActiveEntity !== false
670
616
  const { table } = _getTableName({ query, target }, isSiblingDraft)
671
617
  const cqn = SELECT.from(table)
618
+
672
619
  if (siblingIndex === 0) {
673
620
  const columnCqnPartial = columns.map(col => {
674
621
  const colName = col.ref ? col.ref[col.ref.length - 1] : col
@@ -698,14 +645,16 @@ const _siblingEntity = (
698
645
  for (const key in keys) {
699
646
  if (key !== 'IsActiveEntity') cqn.where([{ ref: [table.as, key] }, '=', { val: keys[key] }])
700
647
  }
648
+
701
649
  if (subScenario) {
702
650
  cqn.where(['exists', subScenario.cqn])
703
651
  }
652
+
704
653
  // in DraftAdminData scenario parent is linked via join
705
654
  if (draftAdminAlias) {
706
655
  cqn.where([{ ref: [draftAdminAlias, 'DraftUUID'] }, '=', { ref: ['draftAdmin', 'DraftUUID'] }])
707
656
  } else if (parentLinks.length) {
708
- cqn.where('(', ...parentLinks, ')')
657
+ cqn.where({ xpr: [...parentLinks] })
709
658
  }
710
659
 
711
660
  return { cqn, scenario: SCENARIO.SIBLING_ENTITY, isSiblingActive: !isSiblingDraft }
@@ -722,6 +671,7 @@ function _siblingSubScenario(nav, siblingIndex, siblingQuery, target, params, mo
722
671
  params: [...params].reverse(),
723
672
  user: req.user
724
673
  }
674
+
725
675
  if (subSiblingIndex > -1) {
726
676
  subScenario = _getSiblingScenario(subReq, [{ val: 1 }], model, subSiblingIndex, subNav, params)
727
677
  if (subSiblingIndex > 0) {
@@ -732,12 +682,14 @@ function _siblingSubScenario(nav, siblingIndex, siblingQuery, target, params, mo
732
682
  }
733
683
  } else {
734
684
  subReq.query = SELECT.from(siblingQuery.SELECT.from).columns([{ val: 1 }])
685
+
735
686
  const existsIdx = siblingQuery.SELECT.where.indexOf('exists')
736
687
  if (existsIdx > -1) subReq.query.where(siblingQuery.SELECT.where.slice(existsIdx, existsIdx + 2))
737
688
  const subOrigFrom = { ref: [...subNav].reverse() }
738
689
  subScenario = _generateCQN(subOrigFrom, subReq, [{ val: 1 }], model)
739
690
  subScenario.cqn.where(onCond)
740
691
  }
692
+
741
693
  return subScenario
742
694
  }
743
695
 
@@ -753,6 +705,7 @@ const _getSiblingScenario = (req, columns, model, siblingIndex, nav) => {
753
705
  queryIndex - 1,
754
706
  query
755
707
  )
708
+
756
709
  if (sibilingQueryFromWhere) return sibilingQueryFromWhere
757
710
  }
758
711
 
@@ -761,6 +714,7 @@ const _getSiblingScenario = (req, columns, model, siblingIndex, nav) => {
761
714
  }
762
715
  }
763
716
  }
717
+
764
718
  const target = { name: query.SELECT.from.ref[0].id || query.SELECT.from.ref[0], as: query.SELECT.from.as }
765
719
  return _siblingEntity(
766
720
  { query, target, params, nav },
@@ -772,6 +726,7 @@ const _getSiblingScenario = (req, columns, model, siblingIndex, nav) => {
772
726
  req
773
727
  )
774
728
  }
729
+
775
730
  return _getSiblingQueryFromWhere(req.query, siblingIndex)
776
731
  }
777
732
 
@@ -807,9 +762,7 @@ const _getDraftDoc = (req, draftName, draftWhere) => {
807
762
  .on([
808
763
  { ref: [req.query.SELECT.from.as || draftName, 'DraftAdministrativeData_DraftUUID'] },
809
764
  '=',
810
- {
811
- ref: ['filterAdmin', 'DraftUUID']
812
- }
765
+ { ref: ['filterAdmin', 'DraftUUID'] }
813
766
  ])
814
767
  .where(_inProcessByUserWhere(req.user.id)),
815
768
  req.query.SELECT,
@@ -835,6 +788,7 @@ const _getOrderByEnrichedColumns = (orderBy, columns, entity) => {
835
788
  }
836
789
  }
837
790
  }
791
+
838
792
  return enrichedCol
839
793
  }
840
794
 
@@ -911,28 +865,24 @@ const _getUnionCQN = (req, draftName, columns, subSelect, draftWhere, model, ent
911
865
  draftDocs.columns(draftColumns)
912
866
 
913
867
  const activeName = activeDocs.SELECT.from.as || (activeDocs.SELECT.from.ref && activeDocs.SELECT.from.ref[0])
914
-
915
868
  const hasDraftWhere = []
916
- for (const key of _getTargetKeys(req)) {
869
+ const targetKeys = _getTargetKeys(req)
870
+ for (const key of targetKeys) {
917
871
  // add 'and' token if not the first iteration
918
872
  if (hasDraftWhere.length) hasDraftWhere.push('and')
919
873
  hasDraftWhere.push({ ref: [activeName, key] }, '=', { ref: [draftName, key] })
920
874
  }
921
875
 
922
- const activeColumns = [
923
- ...columns,
924
- ...enrichedColumns,
925
- ..._filterDraftColumnsBySelected(
926
- _getDraftPropertiesDetermineDraft(req, hasDraftWhere, ensureDraftsSuffix(req.target.name), true),
927
- req.query.SELECT.columns
928
- )
929
- ]
876
+ const draftColumnsBySelected = _filterDraftColumnsBySelected(
877
+ _getDraftPropertiesDetermineDraft(req, hasDraftWhere, ensureDraftsSuffix(req.target.name), true),
878
+ req.query.SELECT.columns
879
+ )
880
+
881
+ const activeColumns = [...columns, ...enrichedColumns, ...draftColumnsBySelected]
930
882
  activeDocs.columns(activeColumns)
931
883
 
932
- activeDocs.where([
933
- 'not exists',
934
- _alignAliasForUnion(ensureNoDraftsSuffix(req.target.name), req.query.SELECT.from.as, subSelect)
935
- ])
884
+ const aliasForUnion = _alignAliasForUnion(ensureNoDraftsSuffix(req.target.name), req.query.SELECT.from.as, subSelect)
885
+ activeDocs.where(['not exists', aliasForUnion])
936
886
 
937
887
  // groupBy, orderBy and limit do not support partial CQNs
938
888
  if (req.query.SELECT.groupBy) {
@@ -958,17 +908,12 @@ const _excludeActiveDraftExists = (req, draftWhere, columns, model) => {
958
908
 
959
909
  const subSelect = SELECT.from(draftName, [1])
960
910
  .join('DRAFT.DraftAdministrativeData', 'filterAdmin')
961
- .on([
962
- { ref: [draftName, 'DraftAdministrativeData_DraftUUID'] },
963
- '=',
964
- {
965
- ref: ['filterAdmin', 'DraftUUID']
966
- }
967
- ])
911
+ .on([{ ref: [draftName, 'DraftAdministrativeData_DraftUUID'] }, '=', { ref: ['filterAdmin', 'DraftUUID'] }])
968
912
  .where(_inProcessByUserWhere(req.user.id))
969
913
 
970
914
  const targetName = ensureNoDraftsSuffix(req.target.name)
971
- for (const key of _getTargetKeys(req)) {
915
+ const targetKeys = _getTargetKeys(req)
916
+ for (const key of targetKeys) {
972
917
  subSelect.where([{ ref: [targetName, key] }, '=', { ref: [draftName, key] }])
973
918
  }
974
919
 
@@ -1013,17 +958,18 @@ const _validatedWithSiblingInProcess = (req, draftWhere, draftParameters, column
1013
958
  _isValidExcludeActiveDraftExists(draftParameters.isActiveEntity, draftParameters.siblingIsActive)
1014
959
  )
1015
960
  return _excludeActiveDraftExists(req, draftWhere, columns, model)
961
+
1016
962
  if (
1017
963
  draftInProcessByUser &&
1018
964
  draftInProcessByUser.op === '!=' &&
1019
965
  _isValidWithDraftLocked(isActiveEntity, siblingIsActive, draftInProcessByUser)
1020
966
  ) {
1021
967
  return _activeWithDraftInProcess(req, draftWhere, columns, req.user.id)
1022
- } else if (draftInProcessByUser && _isValidWithDraftTimeout(isActiveEntity, siblingIsActive, draftInProcessByUser)) {
1023
- return _activeWithDraftInProcess(req, draftWhere, columns, null)
1024
968
  }
1025
969
 
1026
- //
970
+ if (draftInProcessByUser && _isValidWithDraftTimeout(isActiveEntity, siblingIsActive, draftInProcessByUser)) {
971
+ return _activeWithDraftInProcess(req, draftWhere, columns, null)
972
+ }
1027
973
  }
1028
974
 
1029
975
  const _validatedDraftOfWhichIAmOwner = (req, draftWhere, draftParameters, columns) =>
@@ -1034,6 +980,7 @@ const _draftInSubSelect = (where, req) => {
1034
980
  if (xpr) {
1035
981
  return _draftInSubSelect(xpr, req)
1036
982
  }
983
+
1037
984
  if (SELECT && SELECT.where) {
1038
985
  const isActiveEntity = readAndDeleteKeywords(['IsActiveEntity'], SELECT.where, false)
1039
986
  if (isActiveEntity) {
@@ -1065,9 +1012,9 @@ const _generateCQN = (originalFrom, req, columns, model) => {
1065
1012
  siblingScenario = _getSiblingScenario(req, columns, model, siblingIndex, nav)
1066
1013
  if (siblingIndex === 0) {
1067
1014
  return siblingScenario
1068
- } else {
1069
- _mergeSiblingIntoCQN(req.query, siblingScenario, siblingIndex - 1)
1070
1015
  }
1016
+
1017
+ _mergeSiblingIntoCQN(req.query, siblingScenario, siblingIndex - 1)
1071
1018
  }
1072
1019
 
1073
1020
  if (_isDraftAdminScenario(req)) {
@@ -1075,7 +1022,7 @@ const _generateCQN = (originalFrom, req, columns, model) => {
1075
1022
  }
1076
1023
 
1077
1024
  if (!req.query.SELECT.where) {
1078
- return _allActive(req, columns, model)
1025
+ return _allActive(req, columns)
1079
1026
  }
1080
1027
 
1081
1028
  // REVISIT this function does not only read, but modifies where!
@@ -1087,7 +1034,7 @@ const _generateCQN = (originalFrom, req, columns, model) => {
1087
1034
  !(draftParameters.siblingIsActive && draftParameters.siblingIsActive.value.val === null) &&
1088
1035
  !draftParameters.hasDraftEntity
1089
1036
  ) {
1090
- return _allActive(req, columns, model)
1037
+ return _allActive(req, columns)
1091
1038
  }
1092
1039
 
1093
1040
  if (!draftParameters.isActiveEntity) {
@@ -1095,7 +1042,8 @@ const _generateCQN = (originalFrom, req, columns, model) => {
1095
1042
  // this is only the case when navigating into tree
1096
1043
  return _allInactive(req, columns)
1097
1044
  }
1098
- return _allActive(req, columns, model)
1045
+
1046
+ return _allActive(req, columns)
1099
1047
  }
1100
1048
 
1101
1049
  if (draftParameters.hasDraftEntity) {
@@ -1109,14 +1057,10 @@ const _generateCQN = (originalFrom, req, columns, model) => {
1109
1057
  return _validatedDraftOfWhichIAmOwner(req, req.query.SELECT.where, draftParameters, columns)
1110
1058
  }
1111
1059
 
1112
- const _getColumns = ({ query: { SELECT }, target }, model) => {
1113
- return SELECT.columns
1114
- ? SELECT.columns.filter(
1115
- col =>
1116
- (col.ref && !(col.ref[col.ref.length - 1] in DRAFT_COLUMNS_MAP)) || (!col.ref && !(col in DRAFT_COLUMNS_MAP))
1117
- )
1118
- : getColumns(target, { onlyNames: true, removeIgnore: true })
1119
- }
1060
+ const _getColumns = ({ query: { SELECT } }) =>
1061
+ SELECT.columns.filter(
1062
+ col => (col.ref && !(col.ref[col.ref.length - 1] in DRAFT_COLUMNS_MAP)) || (!col.ref && !(col in DRAFT_COLUMNS_MAP))
1063
+ )
1120
1064
 
1121
1065
  const _isIsActiveEntity = element => element.ref && element.ref[element.ref.length - 1] === 'IsActiveEntity'
1122
1066
 
@@ -1170,20 +1114,19 @@ const _adaptDraftColumnsForSiblingEntity = (result, isSiblingActive) => {
1170
1114
  }
1171
1115
 
1172
1116
  const _collectAliases = (from, aliases) => {
1173
- if (from) {
1174
- if (from.ref && from.as) {
1175
- // Actually table names in where annotations should be provided with '.' separator.
1176
- // Normalization to '_' is done for the exceptional case if '_' is still used (based on db table names).
1177
- aliases.set(from.ref[0].replace(/\./g, '_'), from.as)
1178
- } else if (from.args) {
1179
- from.args.forEach(arg => {
1180
- _collectAliases(arg, aliases)
1181
- })
1182
- } else if (from.SET && from.SET.args) {
1183
- from.SET.args.forEach(arg => {
1184
- _collectAliases(arg, aliases)
1185
- })
1186
- }
1117
+ if (!from) return
1118
+ if (from.ref && from.as) {
1119
+ // Actually table names in where annotations should be provided with '.' separator.
1120
+ // Normalization to '_' is done for the exceptional case if '_' is still used (based on db table names).
1121
+ aliases.set(from.ref[0].replace(/\./g, '_'), from.as)
1122
+ } else if (from.args) {
1123
+ from.args.forEach(arg => {
1124
+ _collectAliases(arg, aliases)
1125
+ })
1126
+ } else if (from.SET && from.SET.args) {
1127
+ from.SET.args.forEach(arg => {
1128
+ _collectAliases(arg, aliases)
1129
+ })
1187
1130
  }
1188
1131
  }
1189
1132
 
@@ -1217,6 +1160,7 @@ const _getLocalizedEntity = (model, target, user) => {
1217
1160
  if (cds.env.i18n.for_sqlite.includes(user.locale)) {
1218
1161
  localizedEntity = model.definitions[`${prefix}.${user.locale}.${target.name}`]
1219
1162
  }
1163
+
1220
1164
  return localizedEntity || model.definitions[`${prefix}.${target.name}`]
1221
1165
  }
1222
1166
 
@@ -1241,12 +1185,18 @@ const _getOriginalColumns = req => {
1241
1185
  for (const c of req.query.SELECT.columns) {
1242
1186
  originalColumns[c.ref ? c.ref[c.ref.length - 1] : c.as || c] = true
1243
1187
  }
1188
+
1244
1189
  return originalColumns
1245
1190
  }
1246
1191
 
1192
+ const _handlerStreaming = (req, query) => {
1193
+ adaptStreamCQN(query)
1194
+ query._streaming = true
1195
+ return cds.tx(req).run(query)
1196
+ }
1197
+
1247
1198
  const _postProcess = (result, req, cqnScenario, deleteLastChangeDateTime) => {
1248
1199
  const resultAsArray = Array.isArray(result) ? result : result ? [result] : []
1249
-
1250
1200
  if (!result || !resultAsArray.length) return result
1251
1201
 
1252
1202
  if (cqnScenario.scenario === SCENARIO.SIBLING_ENTITY) {
@@ -1257,11 +1207,11 @@ const _postProcess = (result, req, cqnScenario, deleteLastChangeDateTime) => {
1257
1207
 
1258
1208
  const removeDraftUUIDIfNecessaryFn = removeDraftUUIDIfNecessary(req)
1259
1209
  let notRequestedColumns
1260
- // REVISIT: remove flag cds.env.features.auto_fetch_expand_keys after two month grace period
1261
- if (!req.query.SELECT._4odata && !cds.env.features.auto_fetch_expand_keys) {
1210
+ if (!req.query.SELECT._4odata) {
1262
1211
  const originalColumns = _getOriginalColumns(req)
1263
1212
  notRequestedColumns = originalColumns && Object.keys(resultAsArray[0]).filter(key => !originalColumns[key])
1264
1213
  }
1214
+
1265
1215
  if (cqnScenario.scenario === SCENARIO.DRAFT_ADMIN) {
1266
1216
  _calculateDraftAdminColumns(resultAsArray[0], req.user.id, deleteLastChangeDateTime)
1267
1217
  if (notRequestedColumns) {
@@ -1280,31 +1230,58 @@ const _postProcess = (result, req, cqnScenario, deleteLastChangeDateTime) => {
1280
1230
  return result
1281
1231
  }
1282
1232
 
1233
+ const _fnCompare = elName => c => (c.as && c.as === elName) || (c.ref && c.ref[c.ref.length - 1] === elName)
1234
+ const _adaptColumns4readAfterWrite = (req, cqnScenario, query4sql) => {
1235
+ if (
1236
+ !(req.context.event === 'EDIT' && cqnScenario.scenario === SCENARIO.DRAFT_WHICH_OWNER) &&
1237
+ !(req.context.event === 'draftActivate' && cqnScenario.scenario === SCENARIO.ALL_ACTIVE)
1238
+ )
1239
+ return
1240
+
1241
+ // cleanup columns if not requested with $select or $expand
1242
+ cqnScenario.cqn.SELECT.columns = cqnScenario.cqn.SELECT.columns.reduce((columns, column) => {
1243
+ const elName = column.as || (column.ref && column.ref[column.ref.length - 1])
1244
+ if (query4sql.SELECT.columns.find(_fnCompare(elName)) || elName in req.target.keys) columns.push(column)
1245
+ return columns
1246
+ }, [])
1247
+
1248
+ // add missing keys
1249
+ const isActive = req.context.event === 'draftActivate'
1250
+ // aliasing is fixed by scenarios
1251
+ const alias = isActive ? 'active' : req.target.drafts.name
1252
+ for (const key in req.target.keys) {
1253
+ if (req.target.keys[key].isAssociation) continue
1254
+ if (!cqnScenario.cqn.SELECT.columns.find(_fnCompare(key))) {
1255
+ const column =
1256
+ key === 'IsActiveEntity'
1257
+ ? { val: isActive, as: 'IsActiveEntity', cast: { type: 'cds.Boolean' } }
1258
+ : { ref: [alias, key] }
1259
+ cqnScenario.cqn.SELECT.columns.push(column)
1260
+ }
1261
+ }
1262
+ }
1263
+
1283
1264
  /**
1284
1265
  * Generic Handler for READ requests in the context of draft.
1285
1266
  *
1286
1267
  * @param req
1287
1268
  */
1288
1269
  const _handler = async function (req) {
1270
+ const query = req.query
1271
+ const originalFrom = _copyCQNPartial(query.SELECT.from)
1272
+
1289
1273
  // handle localized here as it was previously handled for req.target
1290
1274
  req.target = _getLocalizedEntity(this.model, req.target, req.user) || req.target
1291
1275
 
1292
- const originalFrom = _copyCQNPartial(req.query.SELECT.from)
1293
-
1294
1276
  // REVISIT DRAFT HANDLING: cqn2cqn4sql must not be called here
1295
1277
  const query4sql = cqn2cqn4sql(req.query, this.model, { _4fiori: true })
1296
1278
 
1297
- // do not clone with Object.assign as that would skip all non-enumerable properties
1298
- const reqClone = { __proto__: req, query: _copyCQNPartial(query4sql) }
1299
-
1300
- // ensure draft restrictions are copied to new query
1301
- reqClone.query._draftRestrictions = req.query._draftRestrictions
1279
+ // Clone the request. Do not clone with Object.assign as that would skip all non-enumerable properties.
1280
+ const reqClone = { __proto__: req, query: query4sql.clone() }
1281
+ // Clone draft restrictions to the cloned query.
1282
+ reqClone.query._draftRestrictions = query._draftRestrictions
1302
1283
 
1303
- if (req.query._streaming) {
1304
- adaptStreamCQN(reqClone.query)
1305
- reqClone.query._streaming = true
1306
- return cds.tx(req).run(reqClone.query)
1307
- }
1284
+ if (query._streaming) return _handlerStreaming(req, reqClone.query)
1308
1285
 
1309
1286
  let cqnScenario
1310
1287
 
@@ -1312,16 +1289,15 @@ const _handler = async function (req) {
1312
1289
  // just to make existing tests working with new parser. not really tested, not needed to be supported
1313
1290
  if (reqClone.query.SELECT.from.SELECT) {
1314
1291
  const subQueryReq = { __proto__: req, query: _copyCQNPartial(_getLastSubQuery(reqClone.query)) }
1315
- cqnScenario = _generateCQN(originalFrom.SELECT.from, subQueryReq, _getColumns(subQueryReq, this.model), this.model)
1292
+ const columns = _getColumns(subQueryReq)
1293
+ cqnScenario = _generateCQN(originalFrom.SELECT.from, subQueryReq, columns, this.model)
1316
1294
  cqnScenario.cqn = _setLastSubQuery(reqClone.query, cqnScenario.cqn)
1317
1295
  } else {
1318
- cqnScenario = _generateCQN(originalFrom, reqClone, _getColumns(reqClone, this.model), this.model)
1296
+ const columns = _getColumns(reqClone)
1297
+ cqnScenario = _generateCQN(originalFrom, reqClone, columns, this.model)
1319
1298
  }
1320
1299
 
1321
- if (!cqnScenario) {
1322
- req.reject(400)
1323
- return
1324
- }
1300
+ if (!cqnScenario) req.reject(400)
1325
1301
 
1326
1302
  // ensure base columns for calculation are selected in draft admin expand
1327
1303
  _adaptDraftAdminExpand(cqnScenario.cqn)
@@ -1341,13 +1317,12 @@ const _handler = async function (req) {
1341
1317
  // unlocalize for db and after handlers as it was before
1342
1318
  req.target = this.model.definitions[ensureUnlocalized(req.target.name)]
1343
1319
 
1344
- const result = await cds.tx(req).send({ query: cqnScenario.cqn, target: req.target })
1320
+ _adaptColumns4readAfterWrite(req, cqnScenario, query4sql)
1345
1321
 
1322
+ const result = await cds.tx(req).send({ query: cqnScenario.cqn, target: req.target })
1346
1323
  return _postProcess(result, req, cqnScenario, enhancedWithLastChangeDateTime)
1347
1324
  }
1348
1325
 
1349
- module.exports = cds.service.impl(function () {
1350
- for (const entity of Object.values(this.entities).filter(e => e._isDraftEnabled)) {
1351
- this.on('READ', entity, _handler)
1352
- }
1326
+ module.exports = cds.service.impl(function (srv, entity) {
1327
+ srv.on('READ', entity, _handler)
1353
1328
  })