@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
@@ -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 = (
@@ -133,6 +120,11 @@ const DRAFT_COLUMNS_CASTED = [
133
120
  }
134
121
  ]
135
122
 
123
+ const DRAFT_COLUMNS_CASTED_WITH_DRAFTADMIN_UUID = [
124
+ ...DRAFT_COLUMNS_CASTED,
125
+ { ref: ['DraftAdministrativeData_DraftUUID'] }
126
+ ]
127
+
136
128
  // default draft values for active entities
137
129
  const _getDefaultDraftProperties = ({ hasDraft, isActive = true, withDraftUUID = true }) => {
138
130
  const columns = [
@@ -162,7 +154,6 @@ const _getDefaultDraftProperties = ({ hasDraft, isActive = true, withDraftUUID =
162
154
  // draft values for active entities with calculated hasDraft property
163
155
  const _getDraftPropertiesDetermineDraft = (req, where, tableName, calcDraftUUID = false) => {
164
156
  const { table } = _getTableName(req, true)
165
-
166
157
  tableName = tableName || table
167
158
 
168
159
  const hasDraftQuery = SELECT.from(tableName, [{ val: 1 }])
@@ -209,18 +200,18 @@ function _copyCQNPartial(partial) {
209
200
  return newPartial
210
201
  }
211
202
 
212
- return partial.ref ? Object.assign({}, partial, { ref: _copyArray(partial.ref) }) : Object.assign({}, partial)
203
+ if (partial.ref) {
204
+ return Object.assign({}, partial, { ref: _copyArray(partial.ref) })
205
+ }
206
+
207
+ return Object.assign({}, partial)
213
208
  }
214
209
 
215
210
  function _copyArray(array) {
216
- return array.map(entry => {
217
- return typeof entry === 'object' && !(entry instanceof String) ? _copyCQNPartial(entry) : entry
218
- })
211
+ return array.map(entry => (typeof entry === 'object' && !(entry instanceof String) ? _copyCQNPartial(entry) : entry))
219
212
  }
220
213
 
221
- const _isValidDraftOfWhichIAmOwner = isActiveEntity => {
222
- return isActiveEntity.op === '=' && _isFalse(isActiveEntity.value.val)
223
- }
214
+ const _isValidDraftOfWhichIAmOwner = isActiveEntity => isActiveEntity.op === '=' && _isFalse(isActiveEntity.value.val)
224
215
 
225
216
  const _isValidActiveWithoutDraft = (isActiveEntity, hasDraftEntity) => {
226
217
  return (
@@ -293,7 +284,7 @@ const _getOuterMostColumns = (columnsFromRequest, additionalDraftColumns) => {
293
284
  // adds base columns 'InProcessByUser' and 'CreatedByUser' to columns param if needed
294
285
  // those are required for calculating 'DraftIsProcessedByMe' and 'DraftIsCreatedByMe'
295
286
  const _ensureDraftAdminColumnsForCalculation = columns => {
296
- columns.forEach((c, i) => {
287
+ columns.forEach(c => {
297
288
  if (c.ref && c.ref[0] === 'DraftIsCreatedByMe' && !columns.find(e => e.ref && e.ref[0] === 'CreatedByUser')) {
298
289
  columns.push({ ref: ['CreatedByUser'] })
299
290
  } else if (
@@ -337,13 +328,7 @@ const _allInactive = (req, columns) => {
337
328
  // ensure only own drafts are read
338
329
  const cqn = SELECT.from(table)
339
330
  .join('DRAFT.DraftAdministrativeData', 'filterAdmin')
340
- .on([
341
- { ref: [table.as, 'DraftAdministrativeData_DraftUUID'] },
342
- '=',
343
- {
344
- ref: ['filterAdmin', 'DraftUUID']
345
- }
346
- ])
331
+ .on([{ ref: [table.as, 'DraftAdministrativeData_DraftUUID'] }, '=', { ref: ['filterAdmin', 'DraftUUID'] }])
347
332
  .where(_inProcessByUserWhere(req.user.id))
348
333
 
349
334
  if (isCount) {
@@ -353,7 +338,6 @@ const _allInactive = (req, columns) => {
353
338
  }
354
339
 
355
340
  cqn.where(req.query.SELECT.where)
356
-
357
341
  return { cqn: getEnrichedCQN(cqn, req.query.SELECT, []), scenario: SCENARIO.ALL_INACTIVE }
358
342
  }
359
343
 
@@ -377,22 +361,7 @@ const _buildWhere = (where, table) => {
377
361
  }
378
362
  }
379
363
 
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) => {
364
+ const _allActive = (req, columns) => {
396
365
  const { table } = _getTableName(req)
397
366
  if (!table.as) {
398
367
  table.as = 'active'
@@ -405,7 +374,6 @@ const _allActive = (req, columns, model) => {
405
374
 
406
375
  const ids = filterKeys(req.target.keys)
407
376
  const isCount = columns.some(element => element.func === 'count')
408
-
409
377
  const xpr = {
410
378
  xpr: [
411
379
  'case',
@@ -437,15 +405,12 @@ const _allActive = (req, columns, model) => {
437
405
  }
438
406
 
439
407
  const scenarioAlias = 'active'
440
-
441
- req.query.SELECT.where = _getWhereWithAppendedDraftRestrictions(req.query.SELECT.where, req, scenarioAlias, model)
408
+ req.query.SELECT.where = _getWhereWithAppendedDraftRestrictions(req.query.SELECT.where, req)
442
409
 
443
410
  if (req.query.SELECT.where) {
444
411
  _buildWhere(req.query.SELECT.where, table)
445
412
  }
446
413
 
447
- _buildOrderBy(req.query, cqn.SELECT.columns, table)
448
-
449
414
  return {
450
415
  cqn: getEnrichedCQN(cqn, req.query.SELECT, req.query.SELECT.where, scenarioAlias),
451
416
  scenario: SCENARIO.ALL_ACTIVE
@@ -472,31 +437,25 @@ const _activeWithoutDraft = (req, draftWhere, columns) => {
472
437
  )
473
438
 
474
439
  const outerMostColumns = _getOuterMostColumns(columns, _getDefaultDraftProperties({ hasDraft: false }))
475
-
476
440
  const cqn = SELECT.from(active.table)
477
441
  .columns(...outerMostColumns)
478
442
  .where(['not exists', subSelect])
479
443
 
480
444
  draftWhere = _getWhereWithAppendedDraftRestrictions(draftWhere, req)
481
-
482
445
  return { cqn: getEnrichedCQN(cqn, req.query.SELECT, draftWhere), scenario: SCENARIO.ACTIVE_WITHOUT_DRAFT }
483
446
  }
484
447
 
485
448
  const _draftOfWhichIAmOwner = (req, draftWhere, columns) => {
486
449
  const { table, name } = _getTableName(req, true)
487
-
488
- const outerMostColumns = _getOuterMostColumns(addColumnAlias(columns, name), DRAFT_COLUMNS_CASTED)
450
+ const outerMostColumns = _getOuterMostColumns(
451
+ addColumnAlias(columns, name),
452
+ DRAFT_COLUMNS_CASTED_WITH_DRAFTADMIN_UUID
453
+ )
489
454
 
490
455
  const cqn = SELECT.from(table)
491
456
  .columns(...outerMostColumns)
492
457
  .join('DRAFT.DraftAdministrativeData', 'filterAdmin')
493
- .on([
494
- { ref: [name, 'DraftAdministrativeData_DraftUUID'] },
495
- '=',
496
- {
497
- ref: ['filterAdmin', 'DraftUUID']
498
- }
499
- ])
458
+ .on([{ ref: [name, 'DraftAdministrativeData_DraftUUID'] }, '=', { ref: ['filterAdmin', 'DraftUUID'] }])
500
459
  .where(_inProcessByUserWhere(req.user.id))
501
460
 
502
461
  return { cqn: getEnrichedCQN(cqn, req.query.SELECT, draftWhere), scenario: SCENARIO.DRAFT_WHICH_OWNER }
@@ -512,13 +471,7 @@ const _activeWithDraftInProcess = (req, draftWhere, columns, isLocked) => {
512
471
  let subSelect = SELECT.from(draftName)
513
472
  .columns(...keys)
514
473
  .join('DRAFT.DraftAdministrativeData', 'filterAdmin')
515
- .on([
516
- { ref: [draftName, 'DraftAdministrativeData_DraftUUID'] },
517
- '=',
518
- {
519
- ref: ['filterAdmin', 'DraftUUID']
520
- }
521
- ])
474
+ .on([{ ref: [draftName, 'DraftAdministrativeData_DraftUUID'] }, '=', { ref: ['filterAdmin', 'DraftUUID'] }])
522
475
 
523
476
  const DRAFT_CANCEL_TIMEOUT_IN_SEC = ((cds.env.drafts && cds.env.drafts.cancellationTimeout) || 15) * 60
524
477
 
@@ -530,25 +483,20 @@ const _activeWithDraftInProcess = (req, draftWhere, columns, isLocked) => {
530
483
  { ref: ['filterAdmin', 'InProcessByUser'] },
531
484
  'is not null',
532
485
  'and',
533
- {
534
- func: 'seconds_between',
535
- args: [{ ref: ['filterAdmin', 'LastChangeDateTime'] }, 'CURRENT_TIMESTAMP']
536
- },
486
+ { func: 'seconds_between', args: [{ ref: ['filterAdmin', 'LastChangeDateTime'] }, 'CURRENT_TIMESTAMP'] },
537
487
  isLocked ? '<' : '>',
538
488
  { val: DRAFT_CANCEL_TIMEOUT_IN_SEC }
539
489
  ])
540
490
 
541
491
  subSelect = keys.reduce(
542
- (select, key) => subSelect.where([{ ref: [active.name, key] }, '=', { ref: [draftName, key] }]),
492
+ (_select, key) => subSelect.where([{ ref: [active.name, key] }, '=', { ref: [draftName, key] }]),
543
493
  subSelect
544
494
  )
545
495
 
546
496
  const outerMostColumns = _getOuterMostColumns(columns, draftColumns)
547
-
548
497
  const cqn = SELECT.from(active.table).columns(outerMostColumns)
549
498
  cqn.where(_getWhereWithAppendedDraftRestrictions([], req))
550
499
  cqn.where(['exists', subSelect])
551
-
552
500
  return { cqn: getEnrichedCQN(cqn, req.query.SELECT, draftWhere), scenario: SCENARIO.DRAFT_IN_PROCESS }
553
501
  }
554
502
 
@@ -572,10 +520,12 @@ const _joinFromWhere = (where, parentAlias, targetAlias) => {
572
520
  return where.reduce((links, el, idx, where) => {
573
521
  if (el.xpr) {
574
522
  const result = _joinFromWhere(el.xpr, parentAlias, targetAlias)
523
+
575
524
  if (result.length) {
576
525
  if (links.length) links.push('and')
577
526
  links.push(...result)
578
527
  }
528
+
579
529
  return links
580
530
  }
581
531
 
@@ -584,11 +534,13 @@ const _joinFromWhere = (where, parentAlias, targetAlias) => {
584
534
  if (links.length) links.push('and')
585
535
  links.push(el, '=', where[idx - 2])
586
536
  }
537
+
587
538
  if (where[idx + 1] && where[idx + 1] === '=' && isTargetRef(where[idx + 2], targetAlias)) {
588
539
  if (links.length) links.push('and')
589
540
  links.push(el, '=', where[idx + 2])
590
541
  }
591
542
  }
543
+
592
544
  return links
593
545
  }, [])
594
546
  }
@@ -609,6 +561,7 @@ const _functionContainsDraftField = obj =>
609
561
  })
610
562
 
611
563
  const _isLogicalFunction = (where, index) => {
564
+ // REVISIT
612
565
  const borders = ['(', ')', 'and', 'or', undefined]
613
566
 
614
567
  return borders.includes(where[index - 1]) && borders.includes(where[index + 1])
@@ -621,6 +574,7 @@ const _getWhereForActive = where => {
621
574
  activeWhere.push({ xpr: _getWhereForActive(where[i].xpr) })
622
575
  continue
623
576
  }
577
+
624
578
  if (_isDraftField(where[i])) {
625
579
  activeWhere.push({ val: null })
626
580
  } else if (_functionContainsDraftField(where[i])) {
@@ -666,9 +620,10 @@ const _siblingEntity = (
666
620
  const subScenario = _siblingSubScenario(nav, siblingIndex, siblingQuery, target, params, model, onCond, req)
667
621
  const isSiblingDraft = subScenario
668
622
  ? subScenario.isSiblingActive || subScenario.scenario === 'ACTIVE' || subScenario.scenario === 'ALL_ACTIVE'
669
- : keys.IsActiveEntity && keys.IsActiveEntity !== 'false'
623
+ : keys.IsActiveEntity && keys.IsActiveEntity !== false
670
624
  const { table } = _getTableName({ query, target }, isSiblingDraft)
671
625
  const cqn = SELECT.from(table)
626
+
672
627
  if (siblingIndex === 0) {
673
628
  const columnCqnPartial = columns.map(col => {
674
629
  const colName = col.ref ? col.ref[col.ref.length - 1] : col
@@ -698,14 +653,16 @@ const _siblingEntity = (
698
653
  for (const key in keys) {
699
654
  if (key !== 'IsActiveEntity') cqn.where([{ ref: [table.as, key] }, '=', { val: keys[key] }])
700
655
  }
656
+
701
657
  if (subScenario) {
702
658
  cqn.where(['exists', subScenario.cqn])
703
659
  }
660
+
704
661
  // in DraftAdminData scenario parent is linked via join
705
662
  if (draftAdminAlias) {
706
663
  cqn.where([{ ref: [draftAdminAlias, 'DraftUUID'] }, '=', { ref: ['draftAdmin', 'DraftUUID'] }])
707
664
  } else if (parentLinks.length) {
708
- cqn.where('(', ...parentLinks, ')')
665
+ cqn.where({ xpr: [...parentLinks] })
709
666
  }
710
667
 
711
668
  return { cqn, scenario: SCENARIO.SIBLING_ENTITY, isSiblingActive: !isSiblingDraft }
@@ -722,6 +679,7 @@ function _siblingSubScenario(nav, siblingIndex, siblingQuery, target, params, mo
722
679
  params: [...params].reverse(),
723
680
  user: req.user
724
681
  }
682
+
725
683
  if (subSiblingIndex > -1) {
726
684
  subScenario = _getSiblingScenario(subReq, [{ val: 1 }], model, subSiblingIndex, subNav, params)
727
685
  if (subSiblingIndex > 0) {
@@ -732,12 +690,14 @@ function _siblingSubScenario(nav, siblingIndex, siblingQuery, target, params, mo
732
690
  }
733
691
  } else {
734
692
  subReq.query = SELECT.from(siblingQuery.SELECT.from).columns([{ val: 1 }])
693
+
735
694
  const existsIdx = siblingQuery.SELECT.where.indexOf('exists')
736
695
  if (existsIdx > -1) subReq.query.where(siblingQuery.SELECT.where.slice(existsIdx, existsIdx + 2))
737
696
  const subOrigFrom = { ref: [...subNav].reverse() }
738
697
  subScenario = _generateCQN(subOrigFrom, subReq, [{ val: 1 }], model)
739
698
  subScenario.cqn.where(onCond)
740
699
  }
700
+
741
701
  return subScenario
742
702
  }
743
703
 
@@ -753,6 +713,7 @@ const _getSiblingScenario = (req, columns, model, siblingIndex, nav) => {
753
713
  queryIndex - 1,
754
714
  query
755
715
  )
716
+
756
717
  if (sibilingQueryFromWhere) return sibilingQueryFromWhere
757
718
  }
758
719
 
@@ -761,6 +722,7 @@ const _getSiblingScenario = (req, columns, model, siblingIndex, nav) => {
761
722
  }
762
723
  }
763
724
  }
725
+
764
726
  const target = { name: query.SELECT.from.ref[0].id || query.SELECT.from.ref[0], as: query.SELECT.from.as }
765
727
  return _siblingEntity(
766
728
  { query, target, params, nav },
@@ -772,6 +734,7 @@ const _getSiblingScenario = (req, columns, model, siblingIndex, nav) => {
772
734
  req
773
735
  )
774
736
  }
737
+
775
738
  return _getSiblingQueryFromWhere(req.query, siblingIndex)
776
739
  }
777
740
 
@@ -807,9 +770,7 @@ const _getDraftDoc = (req, draftName, draftWhere) => {
807
770
  .on([
808
771
  { ref: [req.query.SELECT.from.as || draftName, 'DraftAdministrativeData_DraftUUID'] },
809
772
  '=',
810
- {
811
- ref: ['filterAdmin', 'DraftUUID']
812
- }
773
+ { ref: ['filterAdmin', 'DraftUUID'] }
813
774
  ])
814
775
  .where(_inProcessByUserWhere(req.user.id)),
815
776
  req.query.SELECT,
@@ -835,6 +796,7 @@ const _getOrderByEnrichedColumns = (orderBy, columns, entity) => {
835
796
  }
836
797
  }
837
798
  }
799
+
838
800
  return enrichedCol
839
801
  }
840
802
 
@@ -911,28 +873,24 @@ const _getUnionCQN = (req, draftName, columns, subSelect, draftWhere, model, ent
911
873
  draftDocs.columns(draftColumns)
912
874
 
913
875
  const activeName = activeDocs.SELECT.from.as || (activeDocs.SELECT.from.ref && activeDocs.SELECT.from.ref[0])
914
-
915
876
  const hasDraftWhere = []
916
- for (const key of _getTargetKeys(req)) {
877
+ const targetKeys = _getTargetKeys(req)
878
+ for (const key of targetKeys) {
917
879
  // add 'and' token if not the first iteration
918
880
  if (hasDraftWhere.length) hasDraftWhere.push('and')
919
881
  hasDraftWhere.push({ ref: [activeName, key] }, '=', { ref: [draftName, key] })
920
882
  }
921
883
 
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
- ]
884
+ const draftColumnsBySelected = _filterDraftColumnsBySelected(
885
+ _getDraftPropertiesDetermineDraft(req, hasDraftWhere, ensureDraftsSuffix(req.target.name), true),
886
+ req.query.SELECT.columns
887
+ )
888
+
889
+ const activeColumns = [...columns, ...enrichedColumns, ...draftColumnsBySelected]
930
890
  activeDocs.columns(activeColumns)
931
891
 
932
- activeDocs.where([
933
- 'not exists',
934
- _alignAliasForUnion(ensureNoDraftsSuffix(req.target.name), req.query.SELECT.from.as, subSelect)
935
- ])
892
+ const aliasForUnion = _alignAliasForUnion(ensureNoDraftsSuffix(req.target.name), req.query.SELECT.from.as, subSelect)
893
+ activeDocs.where(['not exists', aliasForUnion])
936
894
 
937
895
  // groupBy, orderBy and limit do not support partial CQNs
938
896
  if (req.query.SELECT.groupBy) {
@@ -958,17 +916,12 @@ const _excludeActiveDraftExists = (req, draftWhere, columns, model) => {
958
916
 
959
917
  const subSelect = SELECT.from(draftName, [1])
960
918
  .join('DRAFT.DraftAdministrativeData', 'filterAdmin')
961
- .on([
962
- { ref: [draftName, 'DraftAdministrativeData_DraftUUID'] },
963
- '=',
964
- {
965
- ref: ['filterAdmin', 'DraftUUID']
966
- }
967
- ])
919
+ .on([{ ref: [draftName, 'DraftAdministrativeData_DraftUUID'] }, '=', { ref: ['filterAdmin', 'DraftUUID'] }])
968
920
  .where(_inProcessByUserWhere(req.user.id))
969
921
 
970
922
  const targetName = ensureNoDraftsSuffix(req.target.name)
971
- for (const key of _getTargetKeys(req)) {
923
+ const targetKeys = _getTargetKeys(req)
924
+ for (const key of targetKeys) {
972
925
  subSelect.where([{ ref: [targetName, key] }, '=', { ref: [draftName, key] }])
973
926
  }
974
927
 
@@ -1013,17 +966,18 @@ const _validatedWithSiblingInProcess = (req, draftWhere, draftParameters, column
1013
966
  _isValidExcludeActiveDraftExists(draftParameters.isActiveEntity, draftParameters.siblingIsActive)
1014
967
  )
1015
968
  return _excludeActiveDraftExists(req, draftWhere, columns, model)
969
+
1016
970
  if (
1017
971
  draftInProcessByUser &&
1018
972
  draftInProcessByUser.op === '!=' &&
1019
973
  _isValidWithDraftLocked(isActiveEntity, siblingIsActive, draftInProcessByUser)
1020
974
  ) {
1021
975
  return _activeWithDraftInProcess(req, draftWhere, columns, req.user.id)
1022
- } else if (draftInProcessByUser && _isValidWithDraftTimeout(isActiveEntity, siblingIsActive, draftInProcessByUser)) {
1023
- return _activeWithDraftInProcess(req, draftWhere, columns, null)
1024
976
  }
1025
977
 
1026
- //
978
+ if (draftInProcessByUser && _isValidWithDraftTimeout(isActiveEntity, siblingIsActive, draftInProcessByUser)) {
979
+ return _activeWithDraftInProcess(req, draftWhere, columns, null)
980
+ }
1027
981
  }
1028
982
 
1029
983
  const _validatedDraftOfWhichIAmOwner = (req, draftWhere, draftParameters, columns) =>
@@ -1034,6 +988,7 @@ const _draftInSubSelect = (where, req) => {
1034
988
  if (xpr) {
1035
989
  return _draftInSubSelect(xpr, req)
1036
990
  }
991
+
1037
992
  if (SELECT && SELECT.where) {
1038
993
  const isActiveEntity = readAndDeleteKeywords(['IsActiveEntity'], SELECT.where, false)
1039
994
  if (isActiveEntity) {
@@ -1065,9 +1020,9 @@ const _generateCQN = (originalFrom, req, columns, model) => {
1065
1020
  siblingScenario = _getSiblingScenario(req, columns, model, siblingIndex, nav)
1066
1021
  if (siblingIndex === 0) {
1067
1022
  return siblingScenario
1068
- } else {
1069
- _mergeSiblingIntoCQN(req.query, siblingScenario, siblingIndex - 1)
1070
1023
  }
1024
+
1025
+ _mergeSiblingIntoCQN(req.query, siblingScenario, siblingIndex - 1)
1071
1026
  }
1072
1027
 
1073
1028
  if (_isDraftAdminScenario(req)) {
@@ -1075,7 +1030,7 @@ const _generateCQN = (originalFrom, req, columns, model) => {
1075
1030
  }
1076
1031
 
1077
1032
  if (!req.query.SELECT.where) {
1078
- return _allActive(req, columns, model)
1033
+ return _allActive(req, columns)
1079
1034
  }
1080
1035
 
1081
1036
  // REVISIT this function does not only read, but modifies where!
@@ -1087,7 +1042,7 @@ const _generateCQN = (originalFrom, req, columns, model) => {
1087
1042
  !(draftParameters.siblingIsActive && draftParameters.siblingIsActive.value.val === null) &&
1088
1043
  !draftParameters.hasDraftEntity
1089
1044
  ) {
1090
- return _allActive(req, columns, model)
1045
+ return _allActive(req, columns)
1091
1046
  }
1092
1047
 
1093
1048
  if (!draftParameters.isActiveEntity) {
@@ -1095,7 +1050,8 @@ const _generateCQN = (originalFrom, req, columns, model) => {
1095
1050
  // this is only the case when navigating into tree
1096
1051
  return _allInactive(req, columns)
1097
1052
  }
1098
- return _allActive(req, columns, model)
1053
+
1054
+ return _allActive(req, columns)
1099
1055
  }
1100
1056
 
1101
1057
  if (draftParameters.hasDraftEntity) {
@@ -1109,14 +1065,10 @@ const _generateCQN = (originalFrom, req, columns, model) => {
1109
1065
  return _validatedDraftOfWhichIAmOwner(req, req.query.SELECT.where, draftParameters, columns)
1110
1066
  }
1111
1067
 
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
- }
1068
+ const _getColumns = ({ query: { SELECT } }) =>
1069
+ SELECT.columns.filter(
1070
+ col => (col.ref && !(col.ref[col.ref.length - 1] in DRAFT_COLUMNS_MAP)) || (!col.ref && !(col in DRAFT_COLUMNS_MAP))
1071
+ )
1120
1072
 
1121
1073
  const _isIsActiveEntity = element => element.ref && element.ref[element.ref.length - 1] === 'IsActiveEntity'
1122
1074
 
@@ -1170,20 +1122,19 @@ const _adaptDraftColumnsForSiblingEntity = (result, isSiblingActive) => {
1170
1122
  }
1171
1123
 
1172
1124
  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
- }
1125
+ if (!from) return
1126
+ if (from.ref && from.as) {
1127
+ // Actually table names in where annotations should be provided with '.' separator.
1128
+ // Normalization to '_' is done for the exceptional case if '_' is still used (based on db table names).
1129
+ aliases.set(from.ref[0].replace(/\./g, '_'), from.as)
1130
+ } else if (from.args) {
1131
+ from.args.forEach(arg => {
1132
+ _collectAliases(arg, aliases)
1133
+ })
1134
+ } else if (from.SET && from.SET.args) {
1135
+ from.SET.args.forEach(arg => {
1136
+ _collectAliases(arg, aliases)
1137
+ })
1187
1138
  }
1188
1139
  }
1189
1140
 
@@ -1217,6 +1168,7 @@ const _getLocalizedEntity = (model, target, user) => {
1217
1168
  if (cds.env.i18n.for_sqlite.includes(user.locale)) {
1218
1169
  localizedEntity = model.definitions[`${prefix}.${user.locale}.${target.name}`]
1219
1170
  }
1171
+
1220
1172
  return localizedEntity || model.definitions[`${prefix}.${target.name}`]
1221
1173
  }
1222
1174
 
@@ -1241,12 +1193,18 @@ const _getOriginalColumns = req => {
1241
1193
  for (const c of req.query.SELECT.columns) {
1242
1194
  originalColumns[c.ref ? c.ref[c.ref.length - 1] : c.as || c] = true
1243
1195
  }
1196
+
1244
1197
  return originalColumns
1245
1198
  }
1246
1199
 
1200
+ const _handlerStreaming = (req, query) => {
1201
+ adaptStreamCQN(query)
1202
+ query._streaming = true
1203
+ return cds.tx(req).run(query)
1204
+ }
1205
+
1247
1206
  const _postProcess = (result, req, cqnScenario, deleteLastChangeDateTime) => {
1248
1207
  const resultAsArray = Array.isArray(result) ? result : result ? [result] : []
1249
-
1250
1208
  if (!result || !resultAsArray.length) return result
1251
1209
 
1252
1210
  if (cqnScenario.scenario === SCENARIO.SIBLING_ENTITY) {
@@ -1257,11 +1215,11 @@ const _postProcess = (result, req, cqnScenario, deleteLastChangeDateTime) => {
1257
1215
 
1258
1216
  const removeDraftUUIDIfNecessaryFn = removeDraftUUIDIfNecessary(req)
1259
1217
  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) {
1218
+ if (!req.query.SELECT._4odata) {
1262
1219
  const originalColumns = _getOriginalColumns(req)
1263
1220
  notRequestedColumns = originalColumns && Object.keys(resultAsArray[0]).filter(key => !originalColumns[key])
1264
1221
  }
1222
+
1265
1223
  if (cqnScenario.scenario === SCENARIO.DRAFT_ADMIN) {
1266
1224
  _calculateDraftAdminColumns(resultAsArray[0], req.user.id, deleteLastChangeDateTime)
1267
1225
  if (notRequestedColumns) {
@@ -1280,31 +1238,60 @@ const _postProcess = (result, req, cqnScenario, deleteLastChangeDateTime) => {
1280
1238
  return result
1281
1239
  }
1282
1240
 
1241
+ const _fnCompare = elName => c => (c.as && c.as === elName) || (c.ref && c.ref[c.ref.length - 1] === elName)
1242
+ const _adaptColumns4readAfterWrite = (req, cqnScenario, query4sql) => {
1243
+ if (
1244
+ !(req.context.event === 'EDIT' && cqnScenario.scenario === SCENARIO.DRAFT_WHICH_OWNER) &&
1245
+ !(req.context.event === 'draftActivate' && cqnScenario.scenario === SCENARIO.ALL_ACTIVE)
1246
+ )
1247
+ return
1248
+
1249
+ // cleanup columns if not requested with $select or $expand
1250
+ cqnScenario.cqn.SELECT.columns = cqnScenario.cqn.SELECT.columns.reduce((columns, column) => {
1251
+ const elName = column.as || (column.ref && column.ref[column.ref.length - 1])
1252
+ if (query4sql.SELECT.columns.find(_fnCompare(elName)) || elName in req.target.keys) columns.push(column)
1253
+ return columns
1254
+ }, [])
1255
+
1256
+ // add missing keys
1257
+ const isActive = req.context.event === 'draftActivate'
1258
+ // aliasing is fixed by scenarios
1259
+ const alias = isActive ? 'active' : req.target.drafts.name
1260
+ for (const key in req.target.keys) {
1261
+ if (req.target.keys[key].isAssociation) continue
1262
+ if (!cqnScenario.cqn.SELECT.columns.find(_fnCompare(key))) {
1263
+ const column =
1264
+ key === 'IsActiveEntity'
1265
+ ? { val: isActive, as: 'IsActiveEntity', cast: { type: 'cds.Boolean' } }
1266
+ : { ref: [alias, key] }
1267
+ cqnScenario.cqn.SELECT.columns.push(column)
1268
+ }
1269
+ }
1270
+ }
1271
+
1283
1272
  /**
1284
1273
  * Generic Handler for READ requests in the context of draft.
1285
1274
  *
1286
1275
  * @param req
1287
1276
  */
1288
1277
  const _handler = async function (req) {
1278
+ const query = req.query
1279
+ const originalFrom = _copyCQNPartial(query.SELECT.from)
1280
+
1289
1281
  // handle localized here as it was previously handled for req.target
1290
1282
  req.target = _getLocalizedEntity(this.model, req.target, req.user) || req.target
1291
1283
 
1292
- const originalFrom = _copyCQNPartial(req.query.SELECT.from)
1293
-
1294
1284
  // REVISIT DRAFT HANDLING: cqn2cqn4sql must not be called here
1295
1285
  const query4sql = cqn2cqn4sql(req.query, this.model, { _4fiori: true })
1296
1286
 
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
1287
+ // Clone the request. Do not clone with Object.assign as that would skip all non-enumerable properties.
1288
+ // REVISIT: query4sql.clone() doesn't really clone the original query, hence _generateCQN will heavily modify
1289
+ // it, e.g. IsActiveEntity is stripped. This is a problem for subsequent handlers which rely on this information.
1290
+ const reqClone = { __proto__: req, query: query4sql.clone() }
1291
+ // Clone draft restrictions to the cloned query.
1292
+ reqClone.query._draftRestrictions = query._draftRestrictions
1302
1293
 
1303
- if (req.query._streaming) {
1304
- adaptStreamCQN(reqClone.query)
1305
- reqClone.query._streaming = true
1306
- return cds.tx(req).run(reqClone.query)
1307
- }
1294
+ if (query._streaming) return _handlerStreaming(req, reqClone.query)
1308
1295
 
1309
1296
  let cqnScenario
1310
1297
 
@@ -1312,16 +1299,15 @@ const _handler = async function (req) {
1312
1299
  // just to make existing tests working with new parser. not really tested, not needed to be supported
1313
1300
  if (reqClone.query.SELECT.from.SELECT) {
1314
1301
  const subQueryReq = { __proto__: req, query: _copyCQNPartial(_getLastSubQuery(reqClone.query)) }
1315
- cqnScenario = _generateCQN(originalFrom.SELECT.from, subQueryReq, _getColumns(subQueryReq, this.model), this.model)
1302
+ const columns = _getColumns(subQueryReq)
1303
+ cqnScenario = _generateCQN(originalFrom.SELECT.from, subQueryReq, columns, this.model)
1316
1304
  cqnScenario.cqn = _setLastSubQuery(reqClone.query, cqnScenario.cqn)
1317
1305
  } else {
1318
- cqnScenario = _generateCQN(originalFrom, reqClone, _getColumns(reqClone, this.model), this.model)
1306
+ const columns = _getColumns(reqClone)
1307
+ cqnScenario = _generateCQN(originalFrom, reqClone, columns, this.model)
1319
1308
  }
1320
1309
 
1321
- if (!cqnScenario) {
1322
- req.reject(400)
1323
- return
1324
- }
1310
+ if (!cqnScenario) req.reject(400)
1325
1311
 
1326
1312
  // ensure base columns for calculation are selected in draft admin expand
1327
1313
  _adaptDraftAdminExpand(cqnScenario.cqn)
@@ -1341,13 +1327,12 @@ const _handler = async function (req) {
1341
1327
  // unlocalize for db and after handlers as it was before
1342
1328
  req.target = this.model.definitions[ensureUnlocalized(req.target.name)]
1343
1329
 
1344
- const result = await cds.tx(req).send({ query: cqnScenario.cqn, target: req.target })
1330
+ _adaptColumns4readAfterWrite(req, cqnScenario, query4sql)
1345
1331
 
1332
+ const result = await cds.tx(req).send({ query: cqnScenario.cqn, target: req.target })
1346
1333
  return _postProcess(result, req, cqnScenario, enhancedWithLastChangeDateTime)
1347
1334
  }
1348
1335
 
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
- }
1336
+ module.exports = cds.service.impl(function (srv, entity) {
1337
+ srv.on('READ', entity, _handler)
1353
1338
  })