@sap/cds 5.9.7 → 6.0.2

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 +267 -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 +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 +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 +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 +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 +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 +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 +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 +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,6 +1,5 @@
1
1
  const { computeColumnsToBeSearched } = require('../../../../libx/_runtime/cds-services/services/utils/columns')
2
2
  const searchToLike = require('./searchToLike')
3
- const { ensureNoDraftsSuffix } = require('./draft')
4
3
  const { getEntityNameFromCQN } = require('./entityFromCqn')
5
4
 
6
5
  const _targetFrom = (cqn, options) => {
@@ -8,12 +7,14 @@ const _targetFrom = (cqn, options) => {
8
7
  return getEntityNameFromCQN(cqn)
9
8
  }
10
9
 
11
- const _search2cqn4sql = (query, model, options = {}) => {
10
+ // convert $search system query option to WHERE/HAVING clause using
11
+ // the operator LIKE or CONTAINS
12
+ const search2cqn4sql = (query, model, options = {}) => {
12
13
  const cqnSearchPhrase = query.SELECT.search
13
14
  if (!cqnSearchPhrase) return
14
15
  const { search2cqn4sql } = options
15
16
  const { entityName, alias } = _targetFrom(query.SELECT.from, options)
16
- const entity = model.definitions[ensureNoDraftsSuffix(entityName)]
17
+ const entity = model.definitions[entityName]
17
18
  const columns = computeColumnsToBeSearched(query, entity, alias)
18
19
 
19
20
  // Call custom (optimized search to cqn for sql implementation) that tries
@@ -30,14 +31,4 @@ const _search2cqn4sql = (query, model, options = {}) => {
30
31
  query._aggregated || /* if new parser */ query.SELECT.groupBy ? query.having(expression) : query.where(expression)
31
32
  }
32
33
 
33
- const search2cqn4sql = (query, model, options) => {
34
- if (query.SELECT.from.SET) {
35
- return query.SELECT.from.SET.args.forEach(arg => _search2cqn4sql(arg, model, options))
36
- }
37
-
38
- return _search2cqn4sql(query, model, options)
39
- }
40
-
41
- // convert $search system query option to WHERE/HAVING clause using
42
- // the operator LIKE or CONTAINS
43
34
  module.exports = search2cqn4sql
@@ -1,19 +1,17 @@
1
1
  const _createLikeComparison = (searchXpr, columns, excludeSearch) => {
2
- const likeExpression = []
2
+ const likeExpression = { xpr: [] }
3
3
 
4
4
  columns.forEach((column, index, columns) => {
5
5
  // if negated search, we need to add is null check
6
+ let currentExpression = likeExpression
6
7
  if (excludeSearch) {
7
- likeExpression.push('(', column, 'IS NULL', 'OR')
8
+ currentExpression = { xpr: [column, 'IS NULL', 'OR'] }
8
9
  }
9
10
 
10
11
  const searchStringEscaped = searchXpr.val.toLowerCase().replace(/(\^|_|%)/g, '^$1')
11
12
 
12
- likeExpression.push(
13
- 'lower',
14
- '(',
15
- column,
16
- ')',
13
+ currentExpression.xpr.push(
14
+ { func: 'lower', args: [column] },
17
15
  excludeSearch ? 'NOT LIKE' : 'LIKE',
18
16
  { val: `%${searchStringEscaped}%` },
19
17
  'ESCAPE',
@@ -21,11 +19,11 @@ const _createLikeComparison = (searchXpr, columns, excludeSearch) => {
21
19
  )
22
20
 
23
21
  if (excludeSearch) {
24
- likeExpression.push(')')
22
+ likeExpression.xpr.push(currentExpression)
25
23
  }
26
24
 
27
25
  if (index !== columns.length - 1) {
28
- likeExpression.push(excludeSearch ? 'AND' : 'OR')
26
+ likeExpression.xpr.push(excludeSearch ? 'AND' : 'OR')
29
27
  }
30
28
  })
31
29
 
@@ -43,15 +41,13 @@ const searchToLike = (cqnSearchPhrase, columns, expression = []) => {
43
41
  }
44
42
 
45
43
  if (element.xpr) {
46
- expression.push('(')
47
- searchToLike(element.xpr, columns, expression)
48
- expression.push(')')
44
+ expression.push({ xpr: searchToLike(element.xpr, columns) })
49
45
  return
50
46
  }
51
47
 
52
48
  const excludeSearch = cqnSearchPhrase[index - 1] === 'not'
53
49
  const likeComparison = _createLikeComparison(element, columns, excludeSearch)
54
- expression.push('(', ...likeComparison, ')')
50
+ expression.push(likeComparison)
55
51
  })
56
52
 
57
53
  return expression
@@ -0,0 +1,35 @@
1
+ const { ensureNoDraftsSuffix, ensureUnlocalized } = require('../../fiori/utils/handler')
2
+
3
+ const _changeStreamProperties = (target, columns, model) => {
4
+ for (let index = 0; index < columns.length; index++) {
5
+ const col = columns[index]
6
+ const name = col.ref && col.ref[col.ref.length - 1]
7
+ const element = name && target.elements[name]
8
+ const type = element && !element['@Core.IsURL'] && element['@Core.MediaType']
9
+
10
+ if (col.ref && type) {
11
+ if (typeof type === 'object') {
12
+ columns[index] = {
13
+ ref: [...col.ref.slice(0, -1), type['=']],
14
+ as: `${name}@odata.mediaContentType`
15
+ }
16
+ } else {
17
+ columns[index] = { val: type, as: `${name}@odata.mediaContentType` }
18
+ }
19
+ } else if (col.expand && col.ref) {
20
+ const tgt = target.elements[col.ref] && target.elements[col.ref].target
21
+ tgt && _changeStreamProperties(model.definitions[ensureUnlocalized(ensureNoDraftsSuffix(tgt))], col.expand, model)
22
+ }
23
+ }
24
+ }
25
+
26
+ const handleStreamProperties = (target, select, model) => {
27
+ const columns = select.SELECT.columns
28
+ if (!columns || !target || !model) return
29
+ if (!select.SELECT._4odata) return
30
+ if (select._streaming) return
31
+
32
+ _changeStreamProperties(target, columns, model)
33
+ }
34
+
35
+ module.exports = { handleStreamProperties }
@@ -1,12 +1,14 @@
1
1
  const resolveStructured = require('./resolveStructured')
2
2
  const { ensureNoDraftsSuffix } = require('../../common/utils/draft')
3
3
  const { traverseFroms } = require('../../common/utils/entityFromCqn')
4
- // TODO move to commons as also used in cqn2cqn4sql
4
+
5
5
  const OPERATIONS_MAP = ['=', '>', '<', '!=', '<>', '>=', '<=', 'like', 'between', 'in', 'not in'].reduce((acc, cur) => {
6
6
  acc[cur] = 1
7
7
  return acc
8
8
  }, {})
9
9
 
10
+ const NOT_EQUAL = { '!=': 1, '<>': 1 }
11
+
10
12
  const _getEntityNamesAndIds = from => {
11
13
  const nameAndIds = []
12
14
  traverseFroms(from, from => {
@@ -34,12 +36,7 @@ const _flattenStructuredInExpand = (column, { _target: expandedEntity }) => {
34
36
 
35
37
  if (element._isStructured) {
36
38
  toBeDeleted.push(propertyName)
37
- flattenedElements.push(
38
- ...resolveStructured(
39
- { structName: element.name, structProperties: expandElement.ref.slice(1) },
40
- element.elements
41
- )
42
- )
39
+ flattenedElements.push(...resolveStructured({ element, structProperties: expandElement.ref.slice(1) }))
43
40
  }
44
41
  }
45
42
 
@@ -64,10 +61,7 @@ const _flattenStructuredOrderBy = (orderBy, csnEntity) => {
64
61
  }
65
62
 
66
63
  if (element._isStructured) {
67
- const flattenedStructOrder = resolveStructured(
68
- { structName: order.ref[0], structProperties: order.ref.slice(1) },
69
- element.elements
70
- )
64
+ const flattenedStructOrder = resolveStructured({ element, structProperties: order.ref.slice(1) })
71
65
  newOrder.push(...flattenedStructOrder.map(element => ({ ref: element.ref, sort: order.sort })))
72
66
  } else {
73
67
  newOrder.push(order)
@@ -91,7 +85,7 @@ const _getVal = (data, name) => {
91
85
 
92
86
  const _filterForStructProperty = (structElement, structData, op, prefix = '', nav = []) => {
93
87
  const filterArray = []
94
- const andOr = op === '!=' ? 'or' : 'and'
88
+ const andOr = op in NOT_EQUAL ? 'or' : 'and'
95
89
 
96
90
  for (const elementName in structElement.elements) {
97
91
  const element = structElement.elements[elementName]
@@ -161,7 +155,7 @@ const _transformStructToFlatWhereHaving = ([first, op, second], resArray, struct
161
155
  const structName = ref[structIdx]
162
156
  const structProperties = ref.slice(structIdx + 1)
163
157
  const nav = structIdx > 0 ? ref.slice(0, structIdx) : []
164
- const flattenedElements = resolveStructured({ structName, structProperties }, structElement.elements)
158
+ const flattenedElements = resolveStructured({ element: structElement, structProperties })
165
159
  const flattenedElement = flattenedElements.find(el => el.ref[0] === [structName, ...structProperties].join('_'))
166
160
  let structData = val
167
161
  try {
@@ -178,7 +172,7 @@ const _transformStructToFlatWhereHaving = ([first, op, second], resArray, struct
178
172
  const filterForStructProperty = _filterForStructProperty(nestedElement, structData, op, prefix, nav)
179
173
  if (filterForStructProperty.length) {
180
174
  filterForStructProperty.pop() // last and/or
181
- if (op === '!=') resArray.push('(', ...filterForStructProperty, ')')
175
+ if (op in NOT_EQUAL) resArray.push({ xpr: [...filterForStructProperty] })
182
176
  else resArray.push(...filterForStructProperty)
183
177
  }
184
178
  }
@@ -210,6 +204,7 @@ const flattenStructuredWhereHaving = (filterArray, csnEntity, model) => {
210
204
  newFilterArray.push({ xpr: flattenStructuredWhereHaving(filterArray[i].xpr, csnEntity, model) })
211
205
  continue
212
206
  }
207
+
213
208
  if (filterArray[i + 1] in OPERATIONS_MAP) {
214
209
  const refElement = filterArray[i].ref ? filterArray[i] : filterArray[i + 2]
215
210
 
@@ -268,9 +263,7 @@ const _flattenColumns = (SELECT, flattenedElements, toBeDeleted, csnEntity, tabl
268
263
 
269
264
  if (element._isStructured) {
270
265
  toBeDeleted.push(structName) // works with aliases?
271
- flattenedElements.push(
272
- ...resolveStructured({ structName, structProperties: cleanedUpRef.slice(1) }, element.elements)
273
- )
266
+ flattenedElements.push(...resolveStructured({ element, structProperties: cleanedUpRef.slice(1) }))
274
267
  }
275
268
  if (cleanedUpRef.length < column.ref.length) {
276
269
  flattenedElements.forEach(e => e.ref.unshift(tableId))
@@ -315,5 +308,6 @@ const flattenStructuredSelect = ({ SELECT }, model) => {
315
308
  module.exports = {
316
309
  flattenStructuredSelect,
317
310
  flattenStructuredWhereHaving,
318
- getNavigationIfStruct
311
+ getNavigationIfStruct,
312
+ OPERATIONS_MAP
319
313
  }
@@ -114,6 +114,7 @@ function _getTemplate(model, cache, targetEntity, callbacks, parent = null, _ent
114
114
  _addSubTemplate(templateElements, elementName, subTemplate)
115
115
  }
116
116
  }
117
+
117
118
  return template
118
119
  }
119
120
 
@@ -143,12 +144,9 @@ module.exports = (usecase, tx, target, ...args) => {
143
144
  const root = (model && model.definitions[target.name]) || target
144
145
  if (!root) return
145
146
 
146
- // tx could be the service itself
147
- // prefer ApplicationService (i.e., tx.context._tx.__proto__)
147
+ // tx could be the service itself -> prefer ApplicationService
148
148
  // REVISIT: context._tx is not a stable API -> pls do not rely on that
149
- const service = tx.context
150
- ? (tx.context._tx && Object.getPrototypeOf(tx.context._tx)) || Object.getPrototypeOf(tx)
151
- : tx
149
+ const service = tx.context ? (tx.context.tx && Object.getPrototypeOf(tx.context.tx)) || Object.getPrototypeOf(tx) : tx
152
150
  if (!service) return
153
151
 
154
152
  // cache templates at service for garbage collection
@@ -6,18 +6,18 @@ const _formatRowContext = (tKey, keyNames, row) => {
6
6
  return `${tKey}(${keyValuePairsSerialized})`
7
7
  }
8
8
 
9
- const _processElement = (processFn, row, key, target, picked = {}, isRoot, path) => {
9
+ const _processElement = (processFn, row, key, target, picked = {}, isRoot, pathSegments) => {
10
10
  const element = (target.elements || target.params)[key]
11
11
  const { plain } = picked
12
12
 
13
13
  if (!plain) return
14
14
  /**
15
- * @type import('../../types/api').templateProcessorProcessFnArgs
15
+ * @type import('../../types/api').templateElementInfo
16
16
  */
17
- const elementInfo = { row, key, element, target, plain, isRoot, path }
18
- if (!element && target._flat2struct && target._flat2struct[key]) {
19
- elementInfo.path = path.slice(0)
20
- elementInfo.path.push(...target._flat2struct[key].map(key => ({ key })))
17
+ const elementInfo = { row, key, element, target, plain, isRoot, pathSegments }
18
+ if (!element && target._flat2struct && target._flat2struct[key] && elementInfo.pathSegments) {
19
+ elementInfo.pathSegments = pathSegments.slice(0)
20
+ elementInfo.pathSegments.push(...target._flat2struct[key])
21
21
  }
22
22
  processFn(elementInfo)
23
23
  }
@@ -26,7 +26,7 @@ const _processRow = (processFn, row, template, tKey, tValue, isRoot, pathOptions
26
26
  const { template: subTemplate, picked } = tValue
27
27
  const key = tKey.split(DELIMITER).pop()
28
28
 
29
- _processElement(processFn, row, key, template.target, picked, isRoot, pathOptions.path)
29
+ _processElement(processFn, row, key, template.target, picked, isRoot, pathOptions.pathSegments)
30
30
 
31
31
  // process deep
32
32
  if (subTemplate && typeof row === 'object' && row) {
@@ -34,29 +34,37 @@ const _processRow = (processFn, row, template, tKey, tValue, isRoot, pathOptions
34
34
  }
35
35
  }
36
36
 
37
+ const _getTargetKeyNames = target => {
38
+ const keyNames = []
39
+ for (const keyName in target.keys) {
40
+ if (target.keys[keyName].__isAssociationStrict) continue
41
+ keyNames.push(keyName)
42
+ }
43
+ return keyNames
44
+ }
45
+
37
46
  const _processComplex = (processFn, row, template, key, pathOptions) => {
38
47
  const value = row && row[key]
39
- const _is2many = Array.isArray(value)
40
- const rows = _is2many ? value : [value]
48
+ const rows = Array.isArray(value) ? value : [value]
41
49
  if (rows.length === 0) return
42
- const keyNames = (template.target.keys && Object.keys(template.target.keys)) || []
50
+ const keyNames = _getTargetKeyNames(template.target)
43
51
 
44
52
  for (let idx = 0; idx < rows.length; idx++) {
45
53
  const row = rows[idx]
46
54
  if (row == null) continue
47
55
  const args = { processFn, row, template, isRoot: false, pathOptions }
48
56
 
49
- let url
57
+ let rowContext
50
58
  if (pathOptions.includeKeyValues) {
51
59
  if (pathOptions.rowKeysGenerator) pathOptions.rowKeysGenerator(keyNames, row, template)
52
- url = _formatRowContext(key, keyNames, Object.assign({}, row, pathOptions.extraKeys))
60
+ rowContext = _formatRowContext(key, keyNames, Object.assign({}, row, pathOptions.extraKeys))
53
61
  }
54
62
 
55
- if (pathOptions.path) pathOptions.path.push({ key, idx: _is2many && idx, url })
63
+ if (pathOptions.pathSegments) pathOptions.pathSegments.push(rowContext || key)
56
64
 
57
65
  templateProcessor(args)
58
66
 
59
- if (pathOptions.path) pathOptions.path.pop()
67
+ if (pathOptions.pathSegments) pathOptions.pathSegments.pop()
60
68
  }
61
69
  }
62
70
 
@@ -96,7 +96,7 @@ module.exports = {
96
96
  val: 1
97
97
  }
98
98
  ],
99
- where: ['(', '%%KEYS%%', ')']
99
+ where: [{ xpr: ['%%KEYS%%'] }]
100
100
  },
101
101
  as: 'HasDraftEntity',
102
102
  cast: {
@@ -125,7 +125,7 @@ module.exports = {
125
125
  ref: ['DraftAdministrativeData_DraftUUID']
126
126
  }
127
127
  ],
128
- where: ['(', '%%KEYS%%', ')']
128
+ where: [{ xpr: ['%%KEYS%%'] }]
129
129
  }
130
130
  }
131
131
  ],
@@ -160,19 +160,9 @@ module.exports = {
160
160
  }
161
161
  ],
162
162
  where: [
163
- '(',
164
- {
165
- ref: ['filterAdmin', 'InProcessByUser']
166
- },
167
- '=',
168
- {
169
- val: '%%USER%%'
170
- },
171
- ')',
163
+ { xpr: [{ ref: ['filterAdmin', 'InProcessByUser'] }, '=', { val: '%%USER%%' }] },
172
164
  'and',
173
- '(',
174
- '%%KEYS%%',
175
- ')'
165
+ { xpr: ['%%KEYS%%'] }
176
166
  ]
177
167
  }
178
168
  }
@@ -30,7 +30,8 @@ class DatabaseService extends cds.Service {
30
30
  // if the tx was initiated in messaging, then this.context._model is not unfolded
31
31
  // -> use this.context._model._4odata if present
32
32
  const { _model } = this.context
33
- this.model = (_model && _model._4odata) || _model || req._model
33
+ if (_model) this.model = _model._4odata || _model
34
+ else this.model = req._model
34
35
  }
35
36
  }
36
37
  this._ensureModel._initial = true
@@ -14,7 +14,7 @@ const _removeParentKeysFromRow = (row, prefix, keys) => {
14
14
  const _autoExpandNavsAndAttachToResult = async (entity, previousResult, depth, options) => {
15
15
  for (const nav in entity._associations) {
16
16
  const navigation = entity._associations[nav]
17
- if (options.onlyCompositions && navigation._isAssociationEffective) continue
17
+ if (options.onlyCompositions && navigation._isAssociationStrict) continue
18
18
 
19
19
  // do not expand backlinks
20
20
  if (navigation._isBacklink) continue
@@ -94,7 +94,7 @@ const _fkForOnCOnd = (onCond, requiredFks) => {
94
94
  const _foreignKeysOfTopLevelNavs = (entity, options) => {
95
95
  const requiredFks = new Set()
96
96
  for (const nav in entity._associations) {
97
- if (options.onlyCompositions && entity._associations[nav]._isAssociationEffective) continue
97
+ if (options.onlyCompositions && entity._associations[nav]._isAssociationStrict) continue
98
98
  const onCond = entity._relations[nav].join('child', 'parent')
99
99
  _fkForOnCOnd(onCond, requiredFks)
100
100
  }
@@ -317,7 +317,9 @@ class JoinCQNFromExpanded {
317
317
  */
318
318
  _adaptWhereOrderBy(cqn, tableAlias) {
319
319
  if (cqn.where) {
320
- cqn.where = cqn.where.map(element => this._adaptWhereElement(element, cqn, tableAlias))
320
+ cqn.where = cqn.where.map(element => {
321
+ return this._adaptWhereElement(element, cqn, tableAlias)
322
+ })
321
323
  }
322
324
 
323
325
  if (cqn.having) {
@@ -603,7 +605,7 @@ class JoinCQNFromExpanded {
603
605
  return {
604
606
  args: [cqn, { ref: [draftTable], as: `${tableAlias}_drafts` }],
605
607
  join: 'left',
606
- on: ['(', ...on, ')']
608
+ on: [{ xpr: [...on] }]
607
609
  }
608
610
  }
609
611
 
@@ -982,8 +984,7 @@ class JoinCQNFromExpanded {
982
984
 
983
985
  if (!column[SKIP_MAPPING]) {
984
986
  mappings[column[IDENTIFIER] || identifier] = as
985
- // REVISIT: remove flag cds.env.features.auto_fetch_expand_keys after two month grace period
986
- if (column[CLEANUP_KEYS] && !cds.env.features.auto_fetch_expand_keys) {
987
+ if (column[CLEANUP_KEYS]) {
987
988
  delete aliasedElement[CLEANUP_KEYS]
988
989
  if (!mappings[CLEANUP_KEYS]) mappings[CLEANUP_KEYS] = {}
989
990
  mappings[CLEANUP_KEYS][column[IDENTIFIER] || identifier] = as
@@ -1599,7 +1600,7 @@ class JoinCQNFromExpanded {
1599
1600
  }
1600
1601
 
1601
1602
  _isNotIncludedIn(columns) {
1602
- if (columns.some(column => isAsteriskColumn(column))) return _ => false
1603
+ if (columns.some(column => isAsteriskColumn(column))) return () => false
1603
1604
  return entry =>
1604
1605
  !columns.some(
1605
1606
  column =>
@@ -1614,7 +1615,7 @@ class JoinCQNFromExpanded {
1614
1615
  * @private
1615
1616
  */
1616
1617
 
1617
- _addMissingJoinElements(columns, joinColumns, keys) {
1618
+ _addMissingJoinElements(columns, joinColumns) {
1618
1619
  const isNotIncludedInColumns = this._isNotIncludedIn(columns)
1619
1620
  for (const joinColumn of joinColumns) {
1620
1621
  if (isNotIncludedInColumns(joinColumn.ref[1])) {
@@ -32,8 +32,8 @@ const _processComplexCategory = ({ row, key, val, category, req, element }) => {
32
32
  category = category.category
33
33
 
34
34
  // propagate keys
35
- if (category === 'propagateForeignKeys' && row[key]) {
36
- propagateForeignKeys(key, row, element._foreignKeys, element._isCompositionEffective)
35
+ if (category === 'propagateForeignKeys' && key in row) {
36
+ propagateForeignKeys(key, row, element._foreignKeys, element.isComposition)
37
37
  return
38
38
  }
39
39
 
@@ -41,12 +41,12 @@ const _processComplexCategory = ({ row, key, val, category, req, element }) => {
41
41
  if (val === undefined && _isManaged(category, req.event)) {
42
42
  if (typeof categoryArgs === 'object') {
43
43
  const val = categoryArgs['=']
44
- if (val.match(/^\$/)) row[key] = val
45
- else row[key] = row[val]
44
+ if (val.match(/^\$/)) {
45
+ row[key] = val === '$uuid' ? cds.utils.uuid() : val
46
+ } else row[key] = row[val]
46
47
  } else {
47
48
  row[key] = categoryArgs
48
49
  }
49
- return
50
50
  }
51
51
 
52
52
  // not null with default for rest response body and ensure utc
@@ -62,7 +62,9 @@ const _processComplexCategory = ({ row, key, val, category, req, element }) => {
62
62
  }
63
63
  }
64
64
 
65
- const _processCategory = ({ category, row, key, element, val, req }) => {
65
+ const _processCategory = (req, category, { row, key, element }) => {
66
+ const val = row[key]
67
+
66
68
  // use args only inside this if (sonar type error warning)
67
69
  if (typeof category === 'object') {
68
70
  _processComplexCategory({ category, row, key, val, req, element })
@@ -106,16 +108,11 @@ const _processCategory = ({ category, row, key, element, val, req }) => {
106
108
  }
107
109
  }
108
110
 
109
- const processorFn =
110
- req =>
111
- ({ row, key, element, plain }) => {
112
- const categories = plain.categories
113
- const val = row[key]
114
-
115
- for (const category of categories) {
116
- _processCategory({ category, row, key, element, val, req })
117
- }
111
+ const _processorFn = req => elementInfo => {
112
+ for (const category of elementInfo.plain.categories) {
113
+ _processCategory(req, category, elementInfo)
118
114
  }
115
+ }
119
116
 
120
117
  const _isVirtualOrCalculated = element => {
121
118
  if (element.virtual) return true
@@ -155,7 +152,7 @@ const _pickCRUD = element => {
155
152
  categories.push({ category: '@cds.on.update', args: element['@cds.on.update'] })
156
153
  }
157
154
 
158
- if (element._isAssociationEffective && !element._target._hasPersistenceSkip) {
155
+ if (element._isAssociationStrict && !element._target._hasPersistenceSkip) {
159
156
  categories.push('associationEffective')
160
157
  }
161
158
 
@@ -223,7 +220,7 @@ function _handler(req) {
223
220
 
224
221
  const data = Array.isArray(req.data) ? req.data : [req.data]
225
222
  for (const row of data) {
226
- templateProcessor({ processFn: processorFn(req), row, template })
223
+ templateProcessor({ processFn: _processorFn(req), row, template })
227
224
  }
228
225
  }
229
226
 
@@ -54,8 +54,7 @@ const _runtimeShallCheckIntegrityFor = (assoc, inclComps) => {
54
54
 
55
55
  // here, no disqualification and no @assert.integrity specified -> global setting
56
56
  const { assert_integrity: ai, assert_integrity_type: ait } = cds.env.features
57
- if (typeof ai === 'string' && ai.match(/individual/i)) return false
58
- if (ait && ait.match(/db/i)) return false
57
+ if (ai && ait && ait.match(/db/i)) return false
59
58
  return true
60
59
  }
61
60
 
@@ -1,8 +1,21 @@
1
1
  // REVISIT: UpdateResult
2
2
  // const UpdateResult = require('../result/UpdateResult')
3
3
 
4
- const { allKeysAreProvided } = require('../../cds-services/services/utils/handlerUtils')
5
4
  const onlyKeysRemain = require('../../common/utils/onlyKeysRemain')
5
+ const { DRAFT_COLUMNS_MAP } = require('../../common/constants/draft')
6
+
7
+ const allKeysAreProvided = req => {
8
+ const data = req.data && (Array.isArray(req.data) ? req.data : [req.data])
9
+ for (const key of Object.values(req.target.keys || {})) {
10
+ if (key._isAssociationStrict || key.name in DRAFT_COLUMNS_MAP) {
11
+ continue
12
+ }
13
+ for (const d of data) {
14
+ if (d[key.name] === undefined) return false
15
+ }
16
+ }
17
+ return true
18
+ }
6
19
 
7
20
  const _enrichKeysFromOldData = (req, oldData) => {
8
21
  const data = req.data && (Array.isArray(req.data) ? req.data : [req.data])
@@ -1,5 +1,4 @@
1
1
  const { timestampToISO } = require('../data-conversion/timestamp')
2
-
3
2
  const { deepCopyObject } = require('../../common/utils/copy')
4
3
 
5
4
  function _arrayWithCount(a, count) {
@@ -29,7 +29,7 @@ const _getFilteredCqns = (cqns, model) => {
29
29
  )
30
30
  if (moreThanManaged) continue
31
31
 
32
- const comps = Object.values(entity.associations || {}).filter(assoc => assoc._isCompositionEffective)
32
+ const comps = Object.values(entity.associations || {}).filter(assoc => assoc.isComposition)
33
33
  for (const comp of comps) {
34
34
  if (_includesCompositionTarget(cqns, comp.target)) {
35
35
  moreThanManaged = true
@@ -56,7 +56,7 @@ class BaseBuilder {
56
56
  _getDatabaseName(entity) {
57
57
  return this._quotingStyle === 'plain'
58
58
  ? entity
59
- : getArtifactCdsPersistenceName(entity, this._quotingStyle, this._csn)
59
+ : getArtifactCdsPersistenceName(entity, this._quotingStyle, this._csn, 'hana') // FIXME: SQL dialect instead of hardcoded 'hana'
60
60
  }
61
61
 
62
62
  _validateQuotingStyle() {
@@ -138,6 +138,7 @@ class ExpressionBuilder extends BaseBuilder {
138
138
  */
139
139
  // eslint-disable-next-line complexity
140
140
  _reseverdKeyWords(objects, i) {
141
+ const NOT_EQUAL = { '!=': 1, '<>': 1 }
141
142
  if (objects[i] === 'not' && objects[i + 1].func) {
142
143
  objects[i + 1].func = `not ${objects[i + 1].func}`
143
144
  return 1
@@ -160,35 +161,19 @@ class ExpressionBuilder extends BaseBuilder {
160
161
  return 0
161
162
  }
162
163
 
163
- if ((objects[i + 1] === '=' || objects[i + 1] === '!=') && objects[i + 2] && objects[i + 2].val === null) {
164
+ if ((objects[i + 1] === '=' || objects[i + 1] in NOT_EQUAL) && objects[i + 2] && objects[i + 2].val === null) {
164
165
  this._addNullOrNotNull(objects[i], objects[i + 1])
165
166
  return 3
166
167
  }
167
168
 
168
- if (objects[i].val === null && (objects[i + 1] === '=' || objects[i + 1] === '!=') && objects[i + 2]) {
169
+ if (objects[i].val === null && (objects[i + 1] === '=' || objects[i + 1] in NOT_EQUAL) && objects[i + 2]) {
169
170
  this._addNullOrNotNull(objects[i + 2], objects[i + 1])
170
171
  return 3
171
172
  }
172
173
 
173
174
  if (/^(not )?in+/i.test(objects[i + 1])) {
174
- if (objects[i + 2] !== '(') {
175
- this._addInOrNotIn(objects[i], objects[i + 1].toUpperCase(), objects[i + 2])
176
- return 3
177
- }
178
-
179
- // map other notation to current notation
180
- const arr = []
181
- let skip = 3
182
- for (let j = i + 3; j < objects.length; j++) {
183
- skip++
184
- if (objects[j] === ')') {
185
- break
186
- } else if (objects[j].val) {
187
- arr.push(objects[j].val)
188
- }
189
- }
190
- this._addInOrNotIn(objects[i], objects[i + 1].toUpperCase(), { val: arr })
191
- return skip
175
+ this._addInOrNotIn(objects[i], objects[i + 1].toUpperCase(), objects[i + 2])
176
+ return 3
192
177
  }
193
178
 
194
179
  return 0
@@ -226,17 +211,6 @@ class ExpressionBuilder extends BaseBuilder {
226
211
  * @private
227
212
  */
228
213
  _addInOrNotIn(reference, operator, values) {
229
- if (values.val === null) {
230
- this._addToOutputObj(new this.ReferenceBuilder(reference, this._options, this._csn).build(), false)
231
- this._outputObj.sql.push('is null')
232
- return true
233
- }
234
-
235
- if (Array.isArray(values.val)) {
236
- this._addArrayForInQuery(reference, operator, values.val)
237
- return true
238
- }
239
-
240
214
  if (Array.isArray(values.list)) {
241
215
  this._expressionElementToSQL(reference)
242
216
  this._outputObj.sql.push(operator)
@@ -297,7 +297,7 @@ class InsertBuilder extends BaseBuilder {
297
297
  _entries(annotatedColumns) {
298
298
  const columns = []
299
299
  const valuesArray = []
300
- const insertAnnotatedColumns = (annotatedColumns && annotatedColumns.insertAnnotatedColumns) || []
300
+ const insertAnnotatedColumns = (annotatedColumns && annotatedColumns.insertAnnotatedColumns) || new Map()
301
301
  const flattenColumnMap = this._getFlattenColumnMap(this._obj.INSERT.entries, { annotatedColumns })
302
302
  const purelyManagedColumns = this._getAnnotatedInsertColumnNames(annotatedColumns).filter(
303
303
  colName => !flattenColumnMap.has(colName)