@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
@@ -1,31 +1,87 @@
1
1
  const cds = require('../../../../cds')
2
- const { SELECT } = cds.ql
2
+ const {
3
+ Request,
4
+ ql: { SELECT }
5
+ } = cds
6
+ const LOG = cds.log()
7
+ const { normalizeError } = require('../../../../common/error/frontend')
3
8
 
4
- const { getDeepSelect } = require('../../../services/utils/handlerUtils')
5
- const { DRAFT_COLUMNS_MAP } = require('../../../../common/constants/draft')
6
- const { filterKeys } = require('../../../../fiori/utils/handler')
9
+ const { getDeepSelect, getSimpleSelectCQN } = require('./handlerUtils')
10
+ const { hasDeepUpdate } = require('../../../../common/composition/update')
11
+ const { WRITE_EVENTS, CDS_EVENTS, DRAFT_MOD_EVENTS } = require('../../../../common/constants/events')
7
12
 
8
- const _getColumns = target => {
9
- const columns = []
10
- for (const k in target.elements) {
11
- if (!target.elements[k].isAssociation && !(k in DRAFT_COLUMNS_MAP)) columns.push(k)
12
- }
13
+ const setLocationHeader = (req, { model }) => {
14
+ const { odataRes } = req._
15
+ const cqn = getSimpleSelectCQN(req.target, req.data)
16
+ const { path: location } = cds.odata.urlify(cqn, { kind: 'odata', model, method: 'GET' })
17
+ odataRes.setHeader('Location', location.replace(/\?.*$/, ''))
18
+ }
19
+
20
+ const _isNoAccessError = e => Number(e.code) === 403 || Number(e.code) === 401
21
+ const _isNotFoundError = e => Number(e.code) === 404
22
+ const _isEntityNotReadableError = e => Number(e.code) === 405
23
+
24
+ const _handleReadError = (err, req) => {
25
+ if (!(_isNoAccessError(err) || _isEntityNotReadableError(err) || _isNotFoundError(err))) throw err
26
+ const log = Object.assign(err, { level: 'ERROR', message: normalizeError(err, req).error.message })
27
+ process.env.NODE_ENV !== 'production' && LOG._warn && LOG.warn(log)
28
+ }
29
+
30
+ const _getOperationQueryColumns = urlQueryOptions => {
31
+ if (!urlQueryOptions || !(urlQueryOptions.$select || urlQueryOptions.$expand)) return []
32
+ const url = []
33
+ if (urlQueryOptions.$select) url.push(`$select=${urlQueryOptions.$select}`)
34
+ if (urlQueryOptions.$expand) url.push(`$expand=${urlQueryOptions.$expand}`)
35
+ const {
36
+ SELECT: { columns }
37
+ } = cds.odata.parse(`?${url.join('&')}`)
13
38
  return columns
14
39
  }
15
40
 
16
- module.exports = async (req, srv) => {
17
- let deepSelect
18
- if (req.event === 'draftActivate') {
19
- const where = filterKeys(req.target.keys).reduce((w, k) => {
20
- w[k] = req.data[k]
21
- return w
22
- }, {})
23
- deepSelect = SELECT.from(req.target).columns(_getColumns(req.target)).where(where)
24
- } else if (req.event === 'UPDATE') {
25
- deepSelect = SELECT.from(req.query.UPDATE.entity, _getColumns(req.target))
41
+ const _isDraftAction = req => req.event in DRAFT_MOD_EVENTS
42
+ const _isActionOrFunction = req => !(req.event in CDS_EVENTS) || _isDraftAction(req)
43
+ const _isWriteWithResponse = req => req.event in WRITE_EVENTS && !(req.event in { CANCEL: 1, DELETE: 1 })
44
+
45
+ const readAfterWrite = async (req, srv, { operation, isBefore } = { isBefore: false }) => {
46
+ let query
47
+
48
+ if (_isActionOrFunction(req)) {
49
+ const { result, returnType } = operation
50
+ query = getSimpleSelectCQN(returnType, result, _getOperationQueryColumns(req._queryOptions))
51
+ if (_isDraftAction(req)) query.where({ IsActiveEntity: req.event === 'draftActivate' })
52
+ } else if (req.event === 'UPDATE' && !hasDeepUpdate(srv.model, req.query)) {
53
+ query = Array.isArray(req.data) ? SELECT.from(req.query.UPDATE.entity) : SELECT.one(req.query.UPDATE.entity)
26
54
  } else {
27
- deepSelect = getDeepSelect(req)
55
+ query = getDeepSelect(req)
56
+ }
57
+ Object.defineProperty(query.SELECT, '_4odata', { value: true })
58
+ // gracefully set location and no body if no read auth or not readable capability
59
+ let result
60
+ try {
61
+ const _req = new Request({ query, event: 'READ', _: req._ })
62
+ result = await srv.dispatch(_req)
63
+ if (result === null && !isBefore && (_isWriteWithResponse(req) || _isDraftAction(req))) {
64
+ // > something must be written and no READ error <=> @restrict or static where
65
+ _req.reject({
66
+ code: 404,
67
+ internal: {
68
+ reason: `No data found for "READ" after "${req.method}" of "${query._target.name}"`,
69
+ source: `"@restrict" or "where" of "${query._target.name}" or underlying entities`
70
+ }
71
+ })
72
+ }
73
+ } catch (e) {
74
+ _handleReadError(e, req)
75
+ result = null
76
+ }
77
+ // draft actions have own logic to set location header
78
+ if (result === null && _isWriteWithResponse(req) && !_isDraftAction(req)) {
79
+ setLocationHeader(req, srv)
28
80
  }
29
- const result = await cds.tx(req).run(deepSelect)
30
81
  return result
31
82
  }
83
+
84
+ module.exports = {
85
+ readAfterWrite,
86
+ setLocationHeader
87
+ }
@@ -8,16 +8,8 @@ const {
8
8
 
9
9
  const getError = require('../../../../common/error')
10
10
 
11
- const _unboundActionsAndFunctions = ['ACTION.IMPORT', 'FUNCTION.IMPORT']
12
- const _unboundCustomOperationKinds = _unboundActionsAndFunctions.reduce((acc, cur) => {
13
- acc[cur] = 1
14
- return acc
15
- }, {})
16
- const _actionsAndFunctions = [..._unboundActionsAndFunctions, 'BOUND.ACTION', 'BOUND.FUNCTION']
17
- const _boundCustomOperationKinds = _actionsAndFunctions.reduce((acc, cur) => {
18
- acc[cur] = 1
19
- return acc
20
- }, {})
11
+ const _unboundActionsAndFunctions = { 'ACTION.IMPORT': 1, 'FUNCTION.IMPORT': 1 }
12
+ const _actionsAndFunctions = { ..._unboundActionsAndFunctions, 'BOUND.ACTION': 1, 'BOUND.FUNCTION': 1 }
21
13
 
22
14
  /**
23
15
  * Checks if a custom operation was requested.
@@ -29,7 +21,7 @@ const _boundCustomOperationKinds = _actionsAndFunctions.reduce((acc, cur) => {
29
21
  */
30
22
  const isCustomOperation = (pathSegments, includingBound = true) => {
31
23
  const kind = pathSegments[pathSegments.length - 1].getKind()
32
- const kinds = includingBound ? _boundCustomOperationKinds : _unboundCustomOperationKinds
24
+ const kinds = includingBound ? _actionsAndFunctions : _unboundActionsAndFunctions
33
25
  if (kind in kinds) {
34
26
  return kind
35
27
  }
@@ -6,6 +6,7 @@ const { big } = require('@sap/cds-foss')
6
6
  const getTemplate = require('../../../../common/utils/template')
7
7
  const templateProcessor = require('../../../../common/utils/templateProcessor')
8
8
  const { omitValue, applyOmitValuesPreference } = require('./omitValues')
9
+ const { setLocationHeader } = require('./readAfterWrite')
9
10
 
10
11
  const METADATA = {
11
12
  $context: '*@odata.context',
@@ -44,6 +45,35 @@ const _getPropertyName = req => {
44
45
  }
45
46
  }
46
47
 
48
+ const _cleanupMetadata = (odataResult, result, req) => {
49
+ if (typeof result !== 'object') return odataResult
50
+ // backwards compatibility for content-type in stream
51
+ if ('*@odata.mediaContentType' in result) result.$mediaContentType = result['*@odata.mediaContentType']
52
+ if ('$mediaContentDispositionFilename' in result && req) {
53
+ const cdt = result.$mediaContentDispositionType || 'attachment'
54
+ req._.odataRes.setHeader(
55
+ 'Content-Disposition',
56
+ `${cdt}; filename="${encodeURIComponent(result.$mediaContentDispositionFilename)}"`
57
+ )
58
+ }
59
+
60
+ const keysToCleanup = {
61
+ // do not set "@odata.context" as it may be inherited of remote service
62
+ $context: true,
63
+ // REVISIT: okra doesn't support content disposition
64
+ $mediaContentDispositionFilename: true,
65
+ $mediaContentDispositionType: true
66
+ }
67
+
68
+ for (const key in METADATA) {
69
+ if (!(key in result)) continue
70
+ if (!keysToCleanup[key]) odataResult[METADATA[key]] = result[key]
71
+ delete result[key]
72
+ }
73
+
74
+ return odataResult
75
+ }
76
+
47
77
  /**
48
78
  * Convert any result to the result object structure, which is expected of odata-v4.
49
79
  *
@@ -51,63 +81,55 @@ const _getPropertyName = req => {
51
81
  * @param {*} [req]
52
82
  * @returns {string | object}
53
83
  */
54
- // eslint-disable-next-line complexity
55
84
  const toODataResult = (result, req) => {
56
85
  if (result == null) return ''
57
86
 
58
- let propertyName, isStream
87
+ let propertyName, isStream, isCollection
59
88
  if (req) {
60
- propertyName = _getPropertyName(req)
61
- isStream =
62
- req._.odataReq.getUriInfo().getLastSegment().getProperty() &&
63
- req._.odataReq.getUriInfo().getLastSegment().getProperty().getType().toString() === 'Edm.Stream'
64
-
65
- const isCollection = !propertyName && req._.odataReq.getUriInfo().getLastSegment().isCollection()
66
- if (isCollection && !Array.isArray(result)) result = [result]
67
- else if (!isCollection && Array.isArray(result)) result = result[0]
89
+ if (cds.env.features.odata_new_parser) {
90
+ propertyName = req._metaInfo.propertyName
91
+ isStream = req._metaInfo.isStream
92
+ isCollection = req._metaInfo.isCollection
93
+ } else {
94
+ propertyName = _getPropertyName(req)
95
+ isStream =
96
+ req._.odataReq.getUriInfo().getLastSegment().getProperty() &&
97
+ req._.odataReq.getUriInfo().getLastSegment().getProperty().getType().toString() === 'Edm.Stream'
98
+
99
+ isCollection =
100
+ !propertyName &&
101
+ !(req.event in { NEW: 1, CREATE: 1, UPDATE: 1, UPSERT: 1, EDIT: 1, PATCH: 1 }) &&
102
+ req._.odataReq.getUriInfo().getLastSegment().isCollection()
103
+ }
68
104
  }
69
105
 
106
+ if (isCollection && !Array.isArray(result)) result = [result]
107
+ else if (!isCollection && Array.isArray(result)) result = result[0]
108
+
70
109
  let value = result
71
110
  if (typeof result === 'object') {
72
111
  if ('value' in result && (result.value instanceof Readable || isStream)) value = result.value
73
112
  else if (propertyName) value = result[propertyName]
74
113
  }
75
114
 
76
- const odataResult = { value }
115
+ const odataResult = _cleanupMetadata({ value }, result, req)
77
116
 
78
- if (typeof result === 'object') {
79
- // backwards compatibility for content-type in stream
80
- if (result['*@odata.mediaContentType']) result.$mediaContentType = result['*@odata.mediaContentType']
81
-
82
- for (const key in METADATA) {
83
- // do not set "@odata.context" as it may be inherited of remote service
84
- if (key === '$context') {
85
- delete result[key]
86
- continue
87
- }
88
-
89
- // REVISIT: okra doesn't support content disposition
90
- if (key === '$mediaContentDispositionFilename' && result[key] && req) {
91
- const cdt = result.$mediaContentDispositionType || 'attachment'
92
- req._.odataRes.setHeader('Content-Disposition', `${cdt}; filename="${encodeURIComponent(result[key])}"`)
93
- delete result[key]
94
- continue
95
- }
96
- if (key === '$mediaContentDispositionType') {
97
- delete result[key]
98
- continue
99
- }
100
-
101
- if (key in result) {
102
- odataResult[METADATA[key]] = result[key]
103
- delete result[key]
104
- }
105
- }
117
+ const { metadata } = _getOptions(req)
118
+ if (cds.env.features.odata_new_parser && metadata !== 'none') {
119
+ return _setContext(odataResult, req, isCollection)
106
120
  }
107
121
 
108
122
  return odataResult
109
123
  }
110
124
 
125
+ const _setContext = (odataResult, req, isCollection) => {
126
+ if (req && req._metaInfo) {
127
+ const result = isCollection ? odataResult : odataResult.value
128
+ if (result != null) Object.assign(result, { [METADATA.$context]: req._metaInfo.contextUrl })
129
+ }
130
+ return odataResult
131
+ }
132
+
111
133
  const addEtags = (row, key) => {
112
134
  row['*@odata.etag'] = row[key]
113
135
  }
@@ -158,12 +180,12 @@ const localizeAfterDraftActivate = (row, key, locale) => {
158
180
  }
159
181
  }
160
182
 
161
- const _processCategory = (category, processArgs, req, options, previousResult) => {
162
- const { row, key, element } = processArgs
183
+ const _processCategory = (req, category, elementInfo, options, previousResult) => {
184
+ const { row, key, element } = elementInfo
163
185
 
164
186
  switch (category) {
165
187
  case '@odata.omitValues':
166
- omitValue(processArgs, req, options.omitValuesPreference, previousResult)
188
+ omitValue(elementInfo, req, options.omitValuesPreference, previousResult)
167
189
  break
168
190
 
169
191
  case '@odata.etag':
@@ -190,13 +212,13 @@ const _processCategory = (category, processArgs, req, options, previousResult) =
190
212
  }
191
213
  }
192
214
 
193
- const _processorFn = (req, previousResult, options) => processArgs => {
194
- const { row, key, plain } = processArgs
215
+ const _processorFn = (req, previousResult, options) => elementInfo => {
216
+ const { row, key, plain } = elementInfo
195
217
  if (typeof row !== 'object' || !Object.prototype.hasOwnProperty.call(row, key)) return
196
218
  const categories = plain.categories
197
219
 
198
220
  for (const category of categories) {
199
- _processCategory(category, processArgs, req, options, previousResult)
221
+ _processCategory(req, category, elementInfo, options, previousResult)
200
222
  }
201
223
  }
202
224
 
@@ -243,15 +265,18 @@ const _assocs = (element, target) => {
243
265
  return []
244
266
  }
245
267
 
246
- const _pick = options => (element, target, parent) => {
268
+ const _pick = options => (element, target) => {
247
269
  const categories = []
248
270
 
249
271
  if (element['@odata.etag']) categories.push('@odata.etag')
250
-
251
272
  if (element._type === 'cds.Decimal') categories.push('@cds.Decimal')
252
273
 
253
274
  categories.push(..._assocs(element, target))
254
275
 
276
+ // REVISIT: It makes no sense to store static values inside the template, it would just
277
+ // blow up the memory of the template.
278
+ // For operations concering _all_ elements, the templating mechanism doesn't make sense
279
+ // and should not be used.
255
280
  if (options.omitValuesPreference) categories.push('@odata.omitValues')
256
281
  if (options.event === 'draftActivate' && options.locale && options.locale !== 'en' && element.localized === true) {
257
282
  categories.push('localizeAfterDraftActivate')
@@ -260,12 +285,15 @@ const _pick = options => (element, target, parent) => {
260
285
  if (categories.length) return { categories }
261
286
  }
262
287
 
263
- const _getOptions = ({ headers, locale, event }) => {
288
+ const _getOptions = req => {
289
+ if (!req) return {}
290
+ const { headers, locale, event } = req
264
291
  const options = {
265
292
  decimals: null,
266
293
  omitValuesPreference: null,
267
294
  locale,
268
- event
295
+ event,
296
+ metadata: 'minimal'
269
297
  }
270
298
 
271
299
  if (!headers) return options
@@ -278,6 +306,9 @@ const _getOptions = ({ headers, locale, event }) => {
278
306
  options.decimals = { exponential: acceptHeader.includes('ExponentialDecimals=true') }
279
307
  }
280
308
 
309
+ const metadataMatch = acceptHeader && acceptHeader.match(/metadata=(minimal|full|none)/)
310
+ if (metadataMatch) options.metadata = metadataMatch[1]
311
+
281
312
  const preferHeader = headers.prefer
282
313
 
283
314
  if (preferHeader && preferHeader.includes('omit-values=')) {
@@ -304,6 +335,7 @@ const postProcess = (req, res, service, result, previousResult) => {
304
335
  const options = _getOptions(req)
305
336
  const cacheKey = _generateCacheKey(headers, options)
306
337
  const parent = _getParent(model, target.name)
338
+ // REVISIT: Why so many templates? -> Create only one (superset) template to reduce memory consumption
307
339
  const template = getTemplate(cacheKey, service, target, { pick: _pick(options) }, parent)
308
340
 
309
341
  if (template.elements.size === 0) return
@@ -318,40 +350,30 @@ const postProcess = (req, res, service, result, previousResult) => {
318
350
  const processFn = _processorFn(req, previousResult, options)
319
351
 
320
352
  for (const row of rows) {
321
- const args = {
353
+ templateProcessor({
322
354
  processFn,
323
355
  row,
324
356
  template
325
- }
326
-
327
- templateProcessor(args)
357
+ })
328
358
  }
329
359
  }
330
360
 
331
361
  applyOmitValuesPreference(res, options.omitValuesPreference)
332
362
  }
333
363
 
334
- const postProcessMinimal = (req, result) => {
335
- const { target } = req
364
+ const postProcessMinimal = (req, service, result) => {
365
+ const { target, timestamp } = req
336
366
 
337
367
  if (!target || !result) return
338
368
 
339
- const etagElement = Object.values(target.elements).find(el => el['@odata.etag'])
340
-
341
- if (!etagElement) return
369
+ setLocationHeader(req, service)
342
370
 
343
- const etag = etagElement.name
344
-
345
- // normalize result to rows
346
- result = result.value && Object.keys(result).filter(k => !k.match(/^\W/)).length === 1 ? result.value : result
347
- const rows = Array.isArray(result) ? result : [result]
348
-
349
- // process each row
350
- for (const row of rows) {
351
- if (typeof row !== 'object' || !Object.prototype.hasOwnProperty.call(row, etag)) return
352
-
353
- addEtags(row, etag)
371
+ const etag = target._etag && target._etag.name
372
+ if (timestamp && etag && etag in result) {
373
+ return { '*@odata.etag': result[etag] === '$now' ? new Date(timestamp).toISOString() : result[etag] }
354
374
  }
375
+
376
+ return null
355
377
  }
356
378
 
357
379
  module.exports = {
@@ -3,11 +3,12 @@ const LOG = cds.log('odata')
3
3
 
4
4
  const { SELECT } = cds.ql
5
5
 
6
- const { targetFromPath, isPathToDraft } = require('../../../../common/utils/cqn')
6
+ const { isPathToDraft } = require('../../../../common/utils/cqn')
7
7
  const { deepCopyArray } = require('../../../../common/utils/copy')
8
8
  const { cqn2cqn4sql } = require('../../../../common/utils/cqn2cqn4sql')
9
9
  const { ensureDraftsSuffix } = require('../../../../fiori/utils/handler')
10
10
  const { removeIsActiveEntityRecursively, isActiveEntityRequested } = require('../../../../fiori/utils/where')
11
+ const { getTransition } = require('../../../../common/utils/resolveView')
11
12
 
12
13
  const isStreaming = segments => {
13
14
  const lastSegment = segments[segments.length - 1]
@@ -44,8 +45,19 @@ const adaptStreamCQN = (cqn, isDraft = false) => {
44
45
  }
45
46
  }
46
47
 
48
+ // eslint-disable-next-line complexity
47
49
  const getStreamProperties = (req, model) => {
48
- const mediaTypeProperty = Object.values(req.target.elements).find(val => val['@Core.MediaType'])
50
+ // new odata parser sets streaming property in SELECT.from
51
+ const ref = (req.query.SELECT.columns && req.query.SELECT.columns[0].ref) || req.query.SELECT.from.ref
52
+ const propertyName = ref[ref.length - 1]
53
+ let mediaTypeProperty
54
+ for (let key in req.target.elements) {
55
+ const val = req.target.elements[key]
56
+ if (val['@Core.MediaType'] && val.name === propertyName) {
57
+ mediaTypeProperty = val
58
+ break
59
+ }
60
+ }
49
61
 
50
62
  let contentType, contentDispositionFilename
51
63
  const columns = []
@@ -56,10 +68,12 @@ const getStreamProperties = (req, model) => {
56
68
  LOG.warn(
57
69
  `@Core.MediaType in entity "${req.target.name}" points to property "${contentTypeProperty}" which was renamed or is not part of the projection. You must update the annotation value.`
58
70
  )
59
- contentTypeProperty = (Object.values(req.target.elements).find(val => val['@Core.IsMediaType']) || {}).name
71
+ const mapping = getTransition(req.target, cds.db).mapping
72
+ const key = [...mapping.entries()].find(({ 1: val }) => val.ref[0] === contentTypeProperty)
73
+ contentTypeProperty = key && key.length && key[0]
60
74
  }
61
75
  if (!req.target.elements[contentTypeProperty]) {
62
- LOG._warn && LOG.warn(`No @Core.IsMediaType found in entity "${req.target.name}".`)
76
+ LOG._warn && LOG.warn(`MediaType ${contentTypeProperty} not found in entity "${req.target.name}".`)
63
77
  } else {
64
78
  columns.push({ ref: [contentTypeProperty], as: 'contentType' })
65
79
  }
@@ -68,12 +82,19 @@ const getStreamProperties = (req, model) => {
68
82
  }
69
83
  if (mediaTypeProperty['@Core.ContentDisposition.Filename']) {
70
84
  if (typeof mediaTypeProperty['@Core.ContentDisposition.Filename'] === 'object') {
71
- const contentDispositionProperty = mediaTypeProperty['@Core.ContentDisposition.Filename']['=']
85
+ let contentDispositionProperty = mediaTypeProperty['@Core.ContentDisposition.Filename']['=']
72
86
  if (!req.target.elements[contentDispositionProperty]) {
73
87
  LOG._warn &&
74
88
  LOG.warn(
75
89
  `@Core.ContentDisposition.Filename in entity "${req.target.name}" points to property "${contentDispositionProperty}" which was renamed or is not part of the projection. You must update the annotation value.`
76
90
  )
91
+ const mapping = getTransition(req.target, cds.db).mapping
92
+ const key = [...mapping.entries()].find(({ 1: val }) => val.ref[0] === contentDispositionProperty)
93
+ contentDispositionProperty = key && key.length && key[0]
94
+ }
95
+ if (!req.target.elements[contentDispositionProperty]) {
96
+ LOG._warn &&
97
+ LOG.warn(`ContentDisposition ${contentDispositionProperty} not found in entity "${req.target.name}".`)
77
98
  } else {
78
99
  columns.push({ ref: [contentDispositionProperty], as: 'contentDispositionFilename' })
79
100
  }
@@ -88,7 +109,7 @@ const getStreamProperties = (req, model) => {
88
109
  let select = SELECT.one.from({ ref: deepCopyArray(req.query.SELECT.from.ref) }).columns(columns)
89
110
 
90
111
  // new parser has media property as last ref element -> remove
91
- if (targetFromPath(select.SELECT.from.ref, model).kind === 'element') select.SELECT.from.ref.pop()
112
+ if (req._metaInfo && req._metaInfo.propertyName) select.SELECT.from.ref.pop()
92
113
 
93
114
  const pathToDraft = isPathToDraft(select.SELECT.from.ref, model)
94
115
  if (req.target._isDraftEnabled && pathToDraft) {
@@ -57,17 +57,6 @@ const _buildTypeErrorObject = (type, value) => {
57
57
  return { type, value }
58
58
  }
59
59
 
60
- const _checkArray = (type, check, data) => {
61
- return data.filter(value => !check(value)).map(value => _buildTypeErrorObject(type, value))
62
- }
63
-
64
- const _checkSingle = (type, check, data) => {
65
- if (!check(data)) {
66
- return [_buildTypeErrorObject(type, data)]
67
- }
68
- return []
69
- }
70
-
71
60
  /**
72
61
  * Validate the return type values of custom operations (actions and functions) for primitive or complex values as
73
62
  * single values or arrays.
@@ -85,17 +74,18 @@ const validateReturnType = (operation, data) => {
85
74
  const returnType = operation.returns.items ? operation.returns.items : operation.returns
86
75
 
87
76
  if (typeof data === 'undefined') return true
77
+ if (returnType['@open']) return true
88
78
 
89
79
  let checkResult
90
80
 
91
81
  // .type of action/function behaves different to .type of other csn elements
92
82
  // Return type contains primitives
93
- if (cds.builtin.types[returnType.type]) {
94
- const check = CDS_TYPE_CHECKS[returnType.type]
95
-
96
- checkResult = operation.returns.items
97
- ? _checkArray(returnType.type, check, data)
98
- : _checkSingle(returnType.type, check, data)
83
+ // eslint-disable-next-line no-proto
84
+ const _type = typeof returnType._type === 'object' ? returnType.__proto__._type : returnType._type // REVISIT: super dirty hack for compiler's to.edmx polluting the csn definitions with ._type -> please use Symbols instead
85
+ const check = CDS_TYPE_CHECKS[_type] // IMPORTANT: use ._type
86
+ if (check) {
87
+ const array = Array.isArray(data) ? data : [data]
88
+ checkResult = array.filter(value => !check(value)).map(value => _buildTypeErrorObject(_type, value))
99
89
  } else {
100
90
  if (typeof data !== 'object') {
101
91
  throw new Error(