@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
@@ -9,13 +9,25 @@ const getEtagElement = entity => {
9
9
 
10
10
  const getComp2oneParents = (entity, model) => {
11
11
  if (!entity) return []
12
- if (entity.own('__comp2oneParents')) return entity.__comp2oneParents
13
- const invalidationFn = element => !(element.is2one && element._isCompositionEffective)
14
- const comp2oneParents = _getUps(entity, model, invalidationFn)
15
- return entity.set('__comp2oneParents', comp2oneParents)
12
+ return _getUps(entity, model).filter(element => element.is2one && element.isComposition)
16
13
  }
17
14
 
18
- const _getUps = (entity, model, invalidationFn) => {
15
+ const setEntityContained = (entity, model, isContained) => {
16
+ if (!entity || entity.kind !== 'entity') return entity
17
+ if ('_isContained' in entity && !isContained) return entity
18
+ if ('_isContained' in entity) delete entity._isContained
19
+ return Object.defineProperty(entity, '_isContained', {
20
+ get() {
21
+ return (
22
+ isContained ||
23
+ !!_getUps(entity, model).find(element => element._isContained && element.parent.name !== entity.name)
24
+ )
25
+ },
26
+ configurable: true
27
+ })
28
+ }
29
+
30
+ const _getUps = (entity, model) => {
19
31
  if (entity.own('__parents')) return entity.__parents
20
32
  const ups = []
21
33
  for (const def of Object.values(model.definitions)) {
@@ -23,7 +35,6 @@ const _getUps = (entity, model, invalidationFn) => {
23
35
  for (const element of Object.values(def.associations)) {
24
36
  if (element.target !== entity.name || element._isBacklink) continue
25
37
  if (element.name === 'SiblingEntity') continue
26
- if (invalidationFn && invalidationFn(element)) continue
27
38
  ups.push(element)
28
39
  }
29
40
  }
@@ -80,86 +91,70 @@ const getDataSubject = (entity, model, role) => {
80
91
  return entity.set(hash, dataSubject)
81
92
  }
82
93
 
83
- const _findInModel = (name, model, namespace) => {
84
- return model.entities(namespace)[name] || model.definitions[`${namespace}.${name}`]
85
- }
86
-
87
- const _resolve = (name, model, namespace) => {
88
- const resolved = _findInModel(name, model, namespace)
94
+ const _resolve = (edmName, model, namespace) => {
95
+ const resolved = model._edmToCSNNameMap[namespace][edmName.replace(/\./g, '_')]
89
96
  // the edm name has an additional suffix 'Parameters' in case of views with parameters
90
- if (!resolved && name.endsWith('Parameters')) {
91
- const viewWithParam = _findInModel(name.replace(/Parameters$/, ''), model, namespace)
97
+ if (!resolved && edmName.endsWith('Parameters')) {
98
+ const viewWithParam = model._edmToCSNNameMap[namespace][edmName.replace(/Parameters$/, '').replace(/\./g, '_')]
92
99
  if (!viewWithParam || !viewWithParam.params) return
93
100
  return viewWithParam
94
101
  }
95
102
  return resolved
96
103
  }
97
104
 
98
- const _findRootEntity = (model, edmName, namespace) => {
105
+ const _findCsnTarget = (edmName, model, namespace) => {
106
+ let target = _resolve(edmName, model, namespace)
107
+ if (target) return target
108
+
109
+ if (!cds.env.effective.odata.structs) return
110
+
111
+ // navigation to structured like `StructuredTypes_structured_nested_` (edmx)
99
112
  const parts = edmName.split('_')
100
- let csnName = parts.shift()
101
- let target = _resolve(csnName, model, namespace)
102
- const len = parts.length
103
- // try to find a correct entity "greedy" and count leftovers (x4 case below)
104
- // e.g. we have 2 entities: 'C_root_' and dependant 'C_root_.kid_'
105
- // for 'C_root_.kid_assoc_prop' it should find 'C_root_.kid_'
106
- // and report 2 leftovers (namely 'assoc' and 'prop')
107
- let left = len
108
- let acc = 0
109
- for (let i = 0; i < len; i++) {
110
- /**
111
- * Calculate CSN name.
112
- * if target in entities connect with .
113
- * if target not in entities connect with _
114
- */
115
- csnName = `${csnName}${_resolve(csnName, model, namespace) ? '.' : '_'}${parts[i]}`
116
- ++acc
117
- if (_resolve(csnName, model, namespace)) {
118
- target = _resolve(csnName, model, namespace)
119
- left -= acc
120
- acc = 0
113
+ let i = parts.length
114
+ let name = edmName
115
+ while (!target && i > 1) {
116
+ // Traverse to find the longest entity name.
117
+ // All weird namings with `.` and `_` are already covered by cache.
118
+ name = name.replace(/_[^_]*$/, '')
119
+ target = _resolve(name, model, namespace)
120
+ i--
121
+ }
122
+ // something left in navigation path => resolving within found entity
123
+ if (i > 0 && target) {
124
+ const left = parts.slice(i - parts.length)
125
+ while (target && left.length) {
126
+ let elm = left.shift()
127
+ while (!target.elements[elm]) elm = `${elm}_${left.shift()}`
128
+ target = target.elements[elm]
121
129
  }
122
130
  }
123
- // make sure we consider leftovers only for x4
124
- return { left: (cds.env.effective.odata.proxies && left) || 0, target: target }
131
+ return target
125
132
  }
126
133
 
127
134
  const findCsnTargetFor = (edmName, model, namespace) => {
128
135
  const cache =
129
136
  model._edmToCSNNameMap || Object.defineProperty(model, '_edmToCSNNameMap', { value: {} })._edmToCSNNameMap
130
- const mapping =
137
+ const edm2csnMap =
131
138
  cache[namespace] ||
132
- Object.defineProperty(cache, namespace, { enumerable: true, configurable: true, value: {} })[namespace]
133
-
134
- if (mapping[edmName]) return mapping[edmName]
135
-
136
- // simple cases
137
- let target = _resolve(edmName, model, namespace) || _resolve(edmName.replace(/_/g, '.'), model, namespace)
138
-
139
- // hard cases
140
- if (!target) {
141
- // probably, a combination of '_' and '.', resolving
142
- const finding = _findRootEntity(model, edmName, namespace)
143
- target = finding.target
144
-
145
- // something left in navigation path => x4 navigation
146
- // resolving within found entity
147
- if (target && finding.left > 0) {
148
- const left = edmName.split('_').slice(-finding.left)
149
- while (target && left.length) {
150
- let elm = left.shift()
151
- while (!target.elements[elm]) elm = `${elm}_${left.shift()}`
152
- target = target.elements[elm]
139
+ Object.defineProperty(cache, namespace, {
140
+ get() {
141
+ const _ = {}
142
+ for (const name in model.definitions) {
143
+ if (!name.startsWith(`${namespace}.`)) continue
144
+ _[name.replace(new RegExp(`^${namespace}\\.`), '').replace(/\./g, '_')] = model.definitions[name]
145
+ }
146
+ return _
153
147
  }
154
- }
155
- }
148
+ })[namespace]
149
+
150
+ const target = _findCsnTarget(edmName, model, namespace)
156
151
 
157
152
  // remember edm <-> csn
158
- if (target) {
159
- mapping[edmName] = target
153
+ if (target && !edm2csnMap[edmName]) {
154
+ edm2csnMap[edmName] = target
160
155
  }
161
156
 
162
- return mapping[edmName]
157
+ return edm2csnMap[edmName]
163
158
  }
164
159
 
165
160
  const getElementDeep = (entity, ref) => {
@@ -177,14 +172,14 @@ const isRootEntity = (definitions, entityName) => {
177
172
  // TODO: There can be unmanaged relations to some parent -> not detected by the following code
178
173
  const associationElements = Object.keys(entity.elements)
179
174
  .map(key => entity.elements[key])
180
- .filter(element => element._isAssociationEffective)
175
+ .filter(element => element._isAssociationStrict)
181
176
 
182
177
  for (const { target } of associationElements) {
183
178
  const parentEntity = definitions[target]
184
179
  for (const parentElementName in parentEntity.elements) {
185
180
  const parentElement = parentEntity.elements[parentElementName]
186
181
  if (
187
- parentElement._isCompositionEffective &&
182
+ parentElement.isComposition &&
188
183
  parentElement.target === entityName &&
189
184
  !(parentElement.parent && ensureNoDraftsSuffix(parentElement.parent.name) === entityName)
190
185
  ) {
@@ -195,24 +190,29 @@ const isRootEntity = (definitions, entityName) => {
195
190
  return true
196
191
  }
197
192
 
198
- function _alias2RefRest(service) {
199
- for (const each of Object.values(service.entities)) {
200
- each._alias2ref = {}
201
- const keys = each.keys
202
- for (const key in keys) {
203
- if (keys[key].elements) {
204
- const structKeys = resolveStructured({ structName: key, structProperties: [] }, keys[key].elements, false, true)
205
- for (const structKey of structKeys) {
206
- if (each._alias2ref[structKey.key] != null) {
207
- // key clash, aliasing not possible
208
- each._alias2ref = {}
209
- return
210
- }
211
- each._alias2ref[structKey.key] = structKey.resolved
212
- }
193
+ const _setAlias2ref = entity => {
194
+ const _ref2alias = {}
195
+ const _alias2ref = {}
196
+ const keys = entity.keys
197
+ for (const key in keys) {
198
+ const structKeys = resolveStructured({ element: keys[key], structProperties: [] }, false, true)
199
+ for (const structKey of structKeys) {
200
+ if (_alias2ref[structKey.key] != null) {
201
+ // key clash, aliasing not possible
202
+ return entity
213
203
  }
204
+ _alias2ref[structKey.key] = structKey.resolved
205
+ _ref2alias[structKey.resolved.join('/')] = key
214
206
  }
215
207
  }
208
+ entity._alias2ref = Object.defineProperty(_alias2ref, '__2alias', { value: _ref2alias, configurable: true })
209
+ return entity
210
+ }
211
+
212
+ function _alias2RefRest(service) {
213
+ for (const each of service.entities) {
214
+ _setAlias2ref(each)
215
+ }
216
216
  }
217
217
 
218
218
  const prefixForStruct = element => {
@@ -230,13 +230,14 @@ function alias2ref(service, edm) {
230
230
  return _alias2RefRest(service)
231
231
  }
232
232
  const defs = edm[service.definition.name]
233
- for (const each of Object.values(service.entities)) {
233
+ for (const each of service.entities) {
234
234
  const def = defs[each.name.replace(service.definition.name + '.', '').replace(/\./g, '_')]
235
235
  if (!def || !def.$Key || def.$Key.every(ele => typeof ele === 'string')) continue
236
- each._alias2ref = {}
236
+ each._alias2ref = Object.defineProperty({}, '__2alias', { value: {}, configurable: true })
237
237
  for (const mapping of def.$Key.filter(ele => typeof ele !== 'string')) {
238
238
  for (const [key, value] of Object.entries(mapping)) {
239
239
  each._alias2ref[key] = value.split('/')
240
+ each._alias2ref.__2alias[value] = key
240
241
  }
241
242
  }
242
243
  }
@@ -274,5 +275,6 @@ module.exports = {
274
275
  alias2ref,
275
276
  getComp2oneParents,
276
277
  prefixForStruct,
277
- getDraftTreeRoot
278
+ getDraftTreeRoot,
279
+ setEntityContained
278
280
  }
@@ -1,19 +1,20 @@
1
1
  const cds = require('../../cds')
2
2
 
3
3
  module.exports = (entryOrRow, keyOrIndex, user, timestamp) => {
4
- if (!entryOrRow[keyOrIndex]) return
4
+ const v = entryOrRow[keyOrIndex]
5
+ if (!v) return
5
6
 
6
7
  // REVISIT: shouldn't be necessary, but sql builder default for user currently cannot be an object (test issue?)
7
8
  // normalize user (object vs. string)
8
9
  user = user && user.id ? user : { id: user || 'anonymous' }
9
10
 
10
- if (entryOrRow[keyOrIndex] === '$user') entryOrRow[keyOrIndex] = user.id
11
- else if (entryOrRow[keyOrIndex] === '$now') entryOrRow[keyOrIndex] = timestamp
12
- else if (entryOrRow[keyOrIndex] === '$uuid') entryOrRow[keyOrIndex] = cds.utils.uuid()
13
- else if (typeof entryOrRow[keyOrIndex] === 'string') {
11
+ if (v === '$user') entryOrRow[keyOrIndex] = user.id
12
+ else if (v === '$now') entryOrRow[keyOrIndex] = timestamp
13
+ else if (v === '$uuid') entryOrRow[keyOrIndex] = cds.utils.uuid()
14
+ else if (typeof v === 'string') {
14
15
  // NOTE: with xsuaa, user attributes are always arrays
15
- const attr = entryOrRow[keyOrIndex].match(/^\$user\.(.*)/)
16
- if (attr && attr.length > 1) {
16
+ const attr = v.match(/^\$user\.(.*)/)
17
+ if (attr) {
17
18
  const val = (user.attr && user.attr[attr[1]]) || null
18
19
  if (Array.isArray(val)) {
19
20
  if (val.length > 1) entryOrRow[keyOrIndex] = JSON.stringify(val)
@@ -39,7 +39,7 @@ const getDraftColumnsCQNForActive = target => {
39
39
  ]
40
40
  }
41
41
 
42
- const getDraftColumnsCQNForDraft = target => {
42
+ const getDraftColumnsCQNForDraft = () => {
43
43
  /*
44
44
  * NOTE: the following with xpr could be used to detect if there really is an active or not, but that breaks tests
45
45
  */
@@ -30,6 +30,10 @@ const _sub = (newOn, subOns = []) => {
30
30
  }
31
31
 
32
32
  const _getSubOns = element => {
33
+ // this only works for on conds with `and`, once we support `or` this needs to be adjusted
34
+
35
+ // TODO : check that no 'or' is in on
36
+
33
37
  const newOn = element.on || []
34
38
  const subOns = _sub(newOn)
35
39
 
@@ -38,6 +42,7 @@ const _getSubOns = element => {
38
42
  // A = B AND C = D AND ...
39
43
  if (subOn.length !== 3) return []
40
44
  }
45
+
41
46
  return subOns.map(subOn => subOn.map(ref => _normalizedRef(ref)))
42
47
  }
43
48
 
@@ -177,15 +182,17 @@ const foreignKeyPropagations = element => {
177
182
  if (element.is2many && element.on) {
178
183
  return _foreignKeyPropagationsFromOn(element)
179
184
  }
185
+
180
186
  if (element.is2one) {
181
- if (!element.on) {
182
- const foreignKeys = _foreignKeys(element)
183
- if (foreignKeys) return _resolvedKeys(foreignKeys, false)
184
- } else {
187
+ if (element.on) {
185
188
  // It's a link through a backlink
186
189
  return _foreignKeyPropagationsFromOn(element)
187
190
  }
191
+
192
+ const foreignKeys = _foreignKeys(element)
193
+ if (foreignKeys) return _resolvedKeys(foreignKeys, false)
188
194
  }
195
+
189
196
  return []
190
197
  }
191
198
 
@@ -218,10 +225,19 @@ const _poorMansLookup = (el, name, foreignKeySource) => {
218
225
  const _createForeignKey = (name, el, parent, foreignKeySource) => {
219
226
  const tk = _poorMansLookup(el, name, foreignKeySource)
220
227
  const navigationCsn = parent.elements[foreignKeySource]
221
- const foreignKeyCsn = Object.assign(Object.create(tk || el), { parent, name, foreignKeySource })
222
- // annotation propagation is not possible via prototyping
223
- for (const key of Object.keys(navigationCsn).filter(key => key.startsWith('@')))
228
+ const key = navigationCsn.key
229
+
230
+ const foreignKeyCsn = Object.assign(Object.create(tk || el), { parent, name, foreignKeySource, key })
231
+ // REVISIT: Overwrite previously defined annotations, maybe there's a better way.
232
+ // We might need to be careful with cached information (__xxx)
233
+ for (const prop in tk || el) {
234
+ if (prop.startsWith('@')) foreignKeyCsn[prop] = undefined
235
+ }
236
+ for (const key in navigationCsn) {
237
+ if (!key.startsWith('@')) continue
224
238
  foreignKeyCsn[key] = navigationCsn[key]
239
+ }
240
+ if ('notNull' in navigationCsn) foreignKeyCsn.notNull = navigationCsn.notNull
225
241
  return foreignKeyCsn
226
242
  }
227
243
 
@@ -93,7 +93,8 @@ const _newOnConditions = (csnElement, path, aliases) => {
93
93
  }
94
94
 
95
95
  const getOnCond = (csnElement, path = [], aliases = { select: '', join: '' }) => {
96
- return ['(', ..._newOnConditions(csnElement, path, aliases), ')']
96
+ const oncond = _newOnConditions(csnElement, path, aliases)
97
+ return [{ xpr: oncond }]
97
98
  }
98
99
 
99
100
  module.exports = {
@@ -1,13 +1,25 @@
1
1
  const { where2obj } = require('./cqn')
2
2
  const { deepCopyArray } = require('./copy')
3
+ const { getOnCond } = require('./generateOnCond')
3
4
 
4
5
  function _getOnCondElements(onCond, onCondElements = []) {
5
6
  const andIndex = onCond.indexOf('and')
6
- const entityKey = onCond[2].ref && onCond[2].ref.join('.')
7
- const entityVal = onCond[2].val
8
- const targetKey = onCond[0].ref && onCond[0].ref.join('.')
9
- const targetVal = onCond[0].val
10
- onCondElements.push({ entityKey, targetKey, entityVal, targetVal })
7
+
8
+ const ref0 = onCond[0].ref
9
+ const ref1 = onCond[2].ref
10
+
11
+ let entityRef, targetRef
12
+ if (ref0 && ref0[0] === 'target') {
13
+ targetRef = ref0
14
+ entityRef = ref1
15
+ } else if (ref1 && ref1[0] === 'target') {
16
+ targetRef = ref1
17
+ entityRef = ref0
18
+ }
19
+
20
+ const entityKey = entityRef && entityRef.slice(1).join('.')
21
+ const targetKey = targetRef && targetRef.slice(1).join('.')
22
+ onCondElements.push({ entityKey, targetKey })
11
23
 
12
24
  if (andIndex !== -1) {
13
25
  _getOnCondElements(onCond.slice(andIndex + 1), onCondElements)
@@ -15,7 +27,7 @@ function _getOnCondElements(onCond, onCondElements = []) {
15
27
  return onCondElements
16
28
  }
17
29
 
18
- function _modifyWhereWithNavigations(where, newWhere, targetKeyElement, keyName) {
30
+ function _modifyWhereWithNavigations(where, newWhere, entityKey, targetKey) {
19
31
  if (where) {
20
32
  // copy where else query will be modified
21
33
  const whereCopy = deepCopyArray(where)
@@ -24,8 +36,8 @@ function _modifyWhereWithNavigations(where, newWhere, targetKeyElement, keyName)
24
36
  }
25
37
 
26
38
  newWhere.forEach(element => {
27
- if (element.ref && targetKeyElement._target.keys[element.ref[0]]) {
28
- element.ref = [keyName + '_' + element.ref[0]]
39
+ if (element.ref && element.ref[0] === targetKey) {
40
+ element.ref = [entityKey]
29
41
  }
30
42
  })
31
43
  }
@@ -40,12 +52,17 @@ function _buildWhereForNavigations(ref, newWhere, model, target) {
40
52
 
41
53
  if (!navigationElement || !navigationElement.on) return
42
54
 
43
- const nextKeys = _getOnCondElements(navigationElement.on)
55
+ const onCond = getOnCond(navigationElement, [], { select: 'source', join: 'target' })
56
+ const nextKeys = _getOnCondElements(onCond[0].xpr)
57
+
58
+ // only add where once in _modifyWhereWithNavigations
59
+ let whereAdded = false
44
60
  for (const key of nextKeys) {
45
- const keyName = key.targetKey.replace(navigationElement.name + '.', '')
46
- const targetKeyElement = navigationElement._target.elements[keyName]
47
- if (targetKeyElement && targetKeyElement.isAssociation) {
48
- _modifyWhereWithNavigations(currentRef.where, newWhere, targetKeyElement, keyName)
61
+ const targetKeyElement = navigationElement._target.elements[key.entityKey]
62
+
63
+ if (targetKeyElement && (targetKeyElement.isAssociation || targetKeyElement._foreignKey4)) {
64
+ _modifyWhereWithNavigations(!whereAdded && currentRef.where, newWhere, key.entityKey, key.targetKey, whereAdded)
65
+ whereAdded = true
49
66
  }
50
67
  }
51
68
  _buildWhereForNavigations(ref.slice(1), newWhere, model, navigationElement._target)
@@ -1,3 +1,4 @@
1
+ const { hasAliasedColumns } = require('../../remote/utils/data')
1
2
  const { revertData } = require('./resolveView')
2
3
 
3
4
  // creates a map with key "remote origin name" and value { as: "projection name"}
@@ -17,6 +18,10 @@ const _createAliasMap = columns => {
17
18
  }
18
19
  if (col.expand) {
19
20
  processor.expand = col.expand
21
+ if (col.expand.some(hasAliasedColumns)) {
22
+ aliasMap || (aliasMap = new Map())
23
+ aliasMap.set(col.ref[col.ref.length - 1], processor)
24
+ }
20
25
  }
21
26
  }
22
27
 
@@ -36,7 +41,7 @@ const handleAliasInResult = (columns, result) => {
36
41
 
37
42
  for (const col in row) {
38
43
  const processor = postProcessor.get(col)
39
- if (processor && processor.as !== col) {
44
+ if (processor && processor.as != null && processor.as !== col) {
40
45
  // if a value for the alias is already present, add it to the cache
41
46
  if (row[processor.as]) {
42
47
  tempCache.set(processor.as, row[processor.as])
@@ -1,35 +1,18 @@
1
1
  const cds = require('../../cds')
2
2
 
3
- const keywords = require('@sap/cds-compiler/lib/base/keywords')
4
3
  const { smartId } = require('@sap/cds-compiler/lib/sql-identifier')
5
4
 
6
5
  let _dialect
7
6
 
8
- const _DEFAULT_RESERVED = new Set(['WHERE', 'GROUP', 'ORDER', 'BY', 'AT', 'NO', 'LIMIT'])
9
- const _COMPILER_RESERVED = {
10
- hana: new Set(keywords.hana),
11
- sqlite: new Set(keywords.sqlite)
12
- }
13
- let _reserved = _DEFAULT_RESERVED
14
-
15
- const _isTruthy = s => s
16
7
  const _isQuoted = s => s.match(/^".*"$/)
17
-
18
8
  const _slugify = s => s.replace(/\./g, '_')
19
9
  const _smartId = s => smartId(_slugify(s), _dialect || 'plain')
20
- const _smartElement = s => {
21
- if (s === '*' || _isQuoted(s)) return s
22
- const upper = s.toUpperCase()
23
- if (_reserved.has(upper)) return upper
24
- return _smartId(s)
25
- }
26
10
 
27
11
  module.exports = {
28
12
  plain: s => {
29
13
  // set _dialect and _reserved once cds.db.kind is set
30
14
  if (!_dialect && cds.db && cds.db.kind) {
31
15
  _dialect = cds.db.options.dialect || cds.db.kind
32
- _reserved = _COMPILER_RESERVED[_dialect] || _DEFAULT_RESERVED
33
16
  }
34
17
 
35
18
  if (typeof s !== 'string') throw new Error(`string expected but ${typeof s} received`)
@@ -37,12 +20,6 @@ module.exports = {
37
20
  // * or already quoted?
38
21
  if (s === '*' || _isQuoted(s)) return s
39
22
 
40
- // expr or space in name?
41
- // REVISIT: default behavior in cds^6?
42
- if (s.match(/\s/) && !cds.env.sql.spaced_columns) {
43
- return s.split(' ').filter(_isTruthy).map(_smartElement).join(' ')
44
- }
45
-
46
23
  return _smartId(s)
47
24
  },
48
25
  quoted: s => `"${s}"`,
@@ -1,57 +1,54 @@
1
- const _flattenProps = (subElement, structName, structProperties, structElement, asRef, withKey) => {
2
- if (subElement.elements) {
1
+ const _flattenProps = (element, structProperties, asRef, withKey, prefix) => {
2
+ if (element.elements) {
3
3
  return _resolveStructured(
4
4
  {
5
- structName: `${structName}_${subElement.name}`,
5
+ element,
6
6
  structProperties: structProperties.slice(1)
7
7
  },
8
- subElement.elements,
9
8
  asRef,
10
- withKey
9
+ withKey,
10
+ prefix
11
11
  )
12
- } else if (subElement.isAssociation) {
13
- if (structProperties.length && subElement.is2one && !subElement.on) {
14
- const flattenedName = `${structName}_${structProperties.join('_')}`
12
+ } else if (element.isAssociation) {
13
+ if (structProperties.length && element.is2one && !element.on) {
14
+ const resolved = [...prefix, ...structProperties]
15
15
  if (withKey) {
16
- return [{ key: structElement, resolved: [flattenedName] }]
16
+ return [{ key: element.name, resolved }]
17
17
  }
18
-
18
+ const flattenedName = resolved.join('_')
19
19
  return asRef ? [{ ref: [flattenedName] }] : [flattenedName]
20
20
  }
21
21
 
22
22
  return []
23
23
  }
24
- const flattenedName = `${structName}_${structElement}`
24
+
25
+ const resolved = [...prefix, element.name]
25
26
  if (withKey) {
26
- return [{ key: structElement, resolved: [flattenedName] }]
27
+ return [{ key: element.name, resolved }]
27
28
  }
28
-
29
+ const flattenedName = resolved.join('_')
29
30
  return asRef ? [{ ref: [flattenedName] }] : [flattenedName]
30
31
  }
31
32
 
32
- const _resolveStructured = ({ structName, structProperties }, subElements, asRef = true, withKey = false) => {
33
- if (!subElements) {
33
+ const _resolveStructured = ({ element, structProperties }, asRef = true, withKey = false, prefix = []) => {
34
+ if (!element.elements) {
34
35
  return []
35
36
  }
36
37
 
38
+ prefix.push(element.name)
39
+
37
40
  // only add from structProperties
38
- if (structProperties.length) {
39
- return _flattenProps(
40
- subElements[structProperties[0]],
41
- structName,
42
- structProperties,
43
- structProperties[0],
44
- asRef,
45
- withKey
46
- )
41
+ if (structProperties && structProperties.length) {
42
+ return _flattenProps(element.elements[structProperties[0]], structProperties, asRef, withKey, prefix)
47
43
  }
48
44
 
49
45
  const flattenedElements = []
50
- for (const structElement in subElements) {
46
+ for (const structElement in element.elements) {
51
47
  flattenedElements.push(
52
- ..._flattenProps(subElements[structElement], structName, structProperties, structElement, asRef, withKey)
48
+ ..._flattenProps(element.elements[structElement], structProperties || [], asRef, withKey, prefix)
53
49
  )
54
50
  }
51
+ prefix.pop()
55
52
  return flattenedElements
56
53
  }
57
54
 
@@ -246,6 +246,7 @@ const _newWhere = (where = [], transition, tableName, alias, isSubselect = false
246
246
  if (whereElement.xpr) {
247
247
  return { xpr: _newWhere(whereElement.xpr, transition, tableName, alias, isSubselect) }
248
248
  }
249
+
249
250
  const newWhereElement = { ...whereElement }
250
251
  if (!whereElement.ref && !whereElement.SELECT && !whereElement.func) return whereElement
251
252
  if (whereElement.SELECT && whereElement.SELECT.where) {
@@ -309,6 +310,8 @@ const _rewriteQueryPath = (path, transitions) => {
309
310
  where: _newWhere(f.where, transitions[i], f.id)
310
311
  }
311
312
  }
313
+
314
+ return f
312
315
  }
313
316
  })
314
317
  }
@@ -656,7 +659,7 @@ const restoreLink = req => {
656
659
  * @returns {*} csn entity or undefined
657
660
  */
658
661
  const findQueryTarget = q => {
659
- return q.SELECT
662
+ return q.SELECT && q.SELECT._transitions
660
663
  ? q.SELECT._transitions[q.SELECT._transitions.length - 1].target
661
664
  : q.INSERT
662
665
  ? q.INSERT._transitions[q.INSERT._transitions.length - 1].target
@@ -83,6 +83,9 @@ const rewriteAsterisks = (query, model, options) => {
83
83
 
84
84
  if (!query.SELECT.columns || !query.SELECT.columns.length) {
85
85
  if (_4db || _4fiori) {
86
+ // REVISIT these are two nasty hacks for UNION and JOIN,
87
+ // which should be implemented generically.
88
+ // Please, do not continue to develop here if possible.
86
89
  if (
87
90
  query.SELECT.from.SET &&
88
91
  query.SELECT.from.SET.args[0] &&