@sap/cds 5.9.8 → 6.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (381) hide show
  1. package/CHANGELOG.md +252 -20
  2. package/apis/services.d.ts +1 -1
  3. package/app/fiori/preview.js +2 -6
  4. package/app/index.js +3 -3
  5. package/bin/build/buildTaskEngine.js +17 -15
  6. package/bin/build/buildTaskFactory.js +29 -19
  7. package/bin/build/buildTaskHandler.js +27 -11
  8. package/bin/build/buildTaskProvider.js +2 -4
  9. package/bin/build/buildTaskProviderFactory.js +11 -16
  10. package/bin/build/constants.js +14 -6
  11. package/bin/build/csv-reader.js +2 -1
  12. package/bin/build/index.js +12 -18
  13. package/bin/build/provider/buildTaskHandlerEdmx.js +3 -39
  14. package/bin/build/provider/buildTaskHandlerFeatureToggles.js +149 -0
  15. package/bin/build/provider/buildTaskHandlerInternal.js +2 -3
  16. package/bin/build/provider/buildTaskProviderInternal.js +108 -239
  17. package/bin/build/provider/fiori/index.js +2 -2
  18. package/bin/build/provider/hana/2migration.js +11 -11
  19. package/bin/build/provider/hana/2tabledata.js +3 -3
  20. package/bin/build/provider/hana/index.js +89 -99
  21. package/bin/build/provider/hana/migrationtable.js +4 -3
  22. package/bin/build/provider/java/index.js +101 -0
  23. package/bin/build/provider/java-cf/index.js +1 -101
  24. package/bin/build/provider/mtx/index.js +83 -41
  25. package/bin/build/provider/mtx/resourcesTarBuilder.js +68 -0
  26. package/bin/build/provider/mtx-sidecar/index.js +80 -0
  27. package/bin/build/provider/node-cf/index.js +1 -308
  28. package/bin/build/provider/nodejs/index.js +189 -0
  29. package/bin/build/util.js +19 -31
  30. package/bin/cds.js +5 -3
  31. package/bin/deploy/to-hana/cfUtil.js +31 -6
  32. package/bin/deploy/to-hana/gitUtil.js +5 -3
  33. package/bin/deploy/to-hana/hana.js +9 -10
  34. package/bin/{build → deploy/to-hana}/mtaUtil.js +10 -9
  35. package/bin/mtx/in-cds.js +19 -7
  36. package/bin/serve.js +56 -21
  37. package/bin/utils/log.js +13 -30
  38. package/bin/version.js +4 -3
  39. package/common.cds +61 -16
  40. package/lib/compile/cdsc.js +3 -2
  41. package/lib/compile/etc/_localized.js +15 -14
  42. package/lib/compile/for/drafts.js +3 -4
  43. package/lib/compile/for/java.js +13 -10
  44. package/lib/compile/for/nodejs.js +8 -8
  45. package/lib/compile/for/odata.js +7 -12
  46. package/lib/compile/for/sql.js +5 -6
  47. package/lib/compile/index.js +5 -4
  48. package/lib/compile/load.js +9 -11
  49. package/lib/compile/minify.js +8 -5
  50. package/lib/compile/parse.js +4 -2
  51. package/lib/compile/resolve.js +18 -15
  52. package/lib/compile/to/edm.js +0 -1
  53. package/lib/compile/to/gql.js +3 -2
  54. package/lib/compile/to/json.js +24 -17
  55. package/lib/connect/bindings.js +3 -2
  56. package/lib/connect/index.js +5 -5
  57. package/lib/core/classes.js +74 -2
  58. package/lib/core/entities.js +52 -3
  59. package/lib/core/reflect.js +2 -1
  60. package/lib/deploy.js +11 -8
  61. package/lib/env/defaults.js +4 -3
  62. package/lib/env/index.js +71 -31
  63. package/lib/env/presets.js +1 -14
  64. package/lib/env/requires.js +70 -20
  65. package/lib/env/serviceBindings.js +147 -0
  66. package/lib/i18n/localize.js +22 -23
  67. package/lib/index.js +148 -144
  68. package/lib/log/errors.js +55 -12
  69. package/lib/log/format/kibana.js +1 -1
  70. package/lib/log/index.js +4 -0
  71. package/lib/ql/SELECT.js +7 -2
  72. package/lib/ql/Whereable.js +8 -2
  73. package/lib/ql/index.js +2 -2
  74. package/lib/req/assert.js +71 -0
  75. package/lib/req/cds-context.js +38 -70
  76. package/lib/req/context.js +34 -21
  77. package/lib/req/request.js +12 -18
  78. package/lib/req/response.js +6 -2
  79. package/lib/req/user.js +30 -22
  80. package/lib/serve/Service-api.js +17 -12
  81. package/lib/serve/Service-dispatch.js +5 -9
  82. package/lib/serve/Service-methods.js +4 -3
  83. package/lib/serve/Transaction.js +24 -21
  84. package/lib/serve/adapters.js +15 -5
  85. package/lib/serve/factory.js +23 -20
  86. package/lib/serve/index.js +51 -54
  87. package/lib/utils/axios.js +8 -12
  88. package/lib/utils/index.js +3 -3
  89. package/lib/utils/resources/index.js +1 -44
  90. package/lib/utils/resources/tar.js +2 -1
  91. package/lib/utils/tests.js +13 -15
  92. package/libx/_runtime/.eslintrc +1 -1
  93. package/libx/_runtime/audit/Service.js +6 -4
  94. package/libx/_runtime/audit/generic/personal/access.js +19 -43
  95. package/libx/_runtime/audit/generic/personal/index.js +40 -34
  96. package/libx/_runtime/audit/generic/personal/modification.js +11 -9
  97. package/libx/_runtime/audit/generic/personal/utils.js +13 -6
  98. package/libx/_runtime/audit/utils/v2.js +6 -3
  99. package/libx/_runtime/auth/index.js +71 -66
  100. package/libx/_runtime/auth/strategies/JWT.js +3 -2
  101. package/libx/_runtime/auth/strategies/mock.js +54 -53
  102. package/libx/_runtime/auth/strategies/xssecUtils.js +3 -4
  103. package/libx/_runtime/auth/strategies/xsuaa.js +3 -2
  104. package/libx/_runtime/auth/utils.js +2 -15
  105. package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +127 -41
  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
@@ -3,12 +3,14 @@ const waitingTime = require('../common-utils/waitingTime')
3
3
  const OutboxRunner = require('./OutboxRunner')
4
4
  const { isStandardError } = require('../../common/error/standardError')
5
5
  const LOG = cds.log('persistent-outbox')
6
+ const util = require('util')
6
7
  const _safeJSONParse = string => {
7
8
  try {
8
9
  return string && JSON.parse(string)
9
- } catch (e) {}
10
+ } catch (_e) {
11
+ // Don't throw
12
+ }
10
13
  }
11
-
12
14
  const outboxRunner = new OutboxRunner()
13
15
  const cdsUser = 'cds.internal.user'
14
16
  const messageProcessorRegistered = Symbol('message processor registered')
@@ -30,7 +32,7 @@ const hasPersistentOutbox = (srv, tenant) => {
30
32
  if (!cds.requires.outbox || cds.requires.outbox.kind !== 'persistent-outbox') return false
31
33
  if (srv.options && srv.options.outbox && srv.options.outbox.kind && srv.options.outbox.kind !== 'persistent-outbox')
32
34
  return false
33
- if (cds._mtxEnabled && tenant && _isProviderTenant(tenant)) return false // no persistence for provider account
35
+ if (cds.mtx && tenant && _isProviderTenant(tenant)) return false // no persistence for provider account
34
36
  return true
35
37
  }
36
38
 
@@ -42,9 +44,9 @@ const isUnrecoverable = (service, error) => {
42
44
 
43
45
  const _processSingleMessage = async (service, message, succeededMessages) => {
44
46
  const msg = _safeJSONParse(message.msg)
47
+ if (!msg) return
45
48
  const userId = msg[cdsUser]
46
49
  delete msg[cdsUser]
47
- if (!msg) return message.ID
48
50
  // Promise resolve is necessary because we want to set `cds.context` only
49
51
  // inside this call
50
52
  return Promise.resolve().then(async () => {
@@ -128,9 +130,13 @@ const processMessages = async (service, tenant, _opts = {}) => {
128
130
  const info = { service: name, event: error.failedMessage.event }
129
131
  if (error.failedMessage.attempts > 0) info.cause = error.failedMessage.error
130
132
  LOG.error('Emit failed', info, `Retrying in ${Math.round(_waitingTime / 1000)} s`)
131
- await UPDATE(messagesEntity)
132
- .where({ ID: error.failedMessage.ID })
133
- .set({ attempts: { '+=': 1 } })
133
+ const data = {
134
+ attempts: { '+=': 1 }
135
+ }
136
+ if (opts.storeLastError) {
137
+ data.lastError = util.inspect(error.failedMessage.error)
138
+ }
139
+ await UPDATE(messagesEntity).where({ ID: error.failedMessage.ID }).set(data)
134
140
  outboxRunner.schedule(
135
141
  {
136
142
  name,
@@ -1,4 +1,3 @@
1
- /* eslint-disable prettier/prettier */
2
1
  const redis = require('redis')
3
2
  const cds = require('../../../lib')
4
3
  const waitingTime = require('./common-utils/waitingTime')
@@ -2,6 +2,8 @@ const cds = require('../cds')
2
2
  const queued = require('./common-utils/queued')
3
3
  const OutboxService = require('./Outbox')
4
4
 
5
+ const appId = require('./common-utils/appId')
6
+
5
7
  const _topic = declared => declared['@topic'] || declared.name
6
8
 
7
9
  let usedTopicOnce = false
@@ -93,6 +95,7 @@ class MessagingService extends OutboxService {
93
95
  let res = topic
94
96
  if (!_inbound && this.options.publishPrefix) res = this.options.publishPrefix + res
95
97
  if (_inbound && this.options.subscribePrefix) res = this.options.subscribePrefix + res
98
+ res = res.replace(/\$appId/g, appId())
96
99
  return res
97
100
  }
98
101
 
@@ -111,7 +114,7 @@ class MessagingService extends OutboxService {
111
114
  const _msg = { ...msg }
112
115
  if (msg.inbound && !cds.context) {
113
116
  // REVISIT: why are all inbound messages executed with privileged user?
114
- cds.context = { tenant: msg.tenant, user: new cds.User.Privileged() }
117
+ cds.context = { tenant: msg.tenant, user: cds.User.privileged }
115
118
  }
116
119
  _msg.event = _warnAndStripTopicPrefix(_msg.event, this.LOG)
117
120
  if (!_msg.headers) _msg.headers = {}
@@ -17,6 +17,7 @@ const { resolveView, getTransition, restoreLink, findQueryTarget } = require('..
17
17
  const { postProcess } = require('../common/utils/postProcessing')
18
18
  const { getKind, run, getDestination, getAdditionalOptions, getReqOptions } = require('./utils/client')
19
19
  const { formatVal } = require('../../odata/utils')
20
+ const { hasAliasedColumns } = require('./utils/data')
20
21
 
21
22
  const _isSimpleCqnQuery = q => typeof q === 'object' && q !== null && !Array.isArray(q) && Object.keys(q).length > 0
22
23
 
@@ -108,10 +109,16 @@ const _handleUnboundActionFunction = (srv, def, req, event) => {
108
109
  return srv.get(url)
109
110
  }
110
111
 
112
+ const _sendV2RequestActionFunction = (srv, def, url) => {
113
+ return def.kind === 'function'
114
+ ? srv.send({ method: 'GET', path: url, _returnType: def.returns })
115
+ : srv.send({ method: 'POST', path: url, data: {}, _returnType: def.returns })
116
+ }
117
+
111
118
  const _handleV2ActionFunction = (srv, def, req, event, kind) => {
112
119
  const url =
113
120
  Object.keys(req.data).length > 0 ? _buildPartialUrlFunctions(`/${event}`, req.data, def.params, kind) : `/${event}`
114
- return def.kind === 'function' ? srv.get(url) : srv.post(url, {})
121
+ return _sendV2RequestActionFunction(srv, def, url)
115
122
  }
116
123
 
117
124
  const _handleV2BoundActionFunction = (srv, def, req, event, kind) => {
@@ -128,7 +135,7 @@ const _handleV2BoundActionFunction = (srv, def, req, event, kind) => {
128
135
  params.push(...keys)
129
136
  }
130
137
  const url = `${`/${event}`}?${params.join('&')}`
131
- return def.kind === 'function' ? srv.get(url) : srv.post(url, {})
138
+ return _sendV2RequestActionFunction(srv, def, url)
132
139
  }
133
140
 
134
141
  const _addHandlerActionFunction = (srv, def, target) => {
@@ -150,7 +157,7 @@ const _addHandlerActionFunction = (srv, def, target) => {
150
157
  }
151
158
 
152
159
  const _selectOnlyWithAlias = q => {
153
- return q && q.SELECT && !q.SELECT._transitions && q.SELECT.columns && q.SELECT.columns.some(c => c.as)
160
+ return q && q.SELECT && !q.SELECT._transitions && q.SELECT.columns && q.SELECT.columns.some(hasAliasedColumns)
154
161
  }
155
162
 
156
163
  const resolvedTargetOfQuery = q => {
@@ -190,20 +197,19 @@ class RemoteService extends cds.Service {
190
197
  }
191
198
 
192
199
  this.on('*', async (req, next) => {
193
- let { query } = req
200
+ const { query } = req
194
201
  if (!query && !(typeof req.path === 'string')) return next()
195
- if (cds.env.features.resolve_views === false && typeof query === 'object' && this.model) {
196
- query = resolveView(query, this.model, this)
197
- }
198
202
 
199
203
  const resolvedTarget = resolvedTargetOfQuery(query) || getTransition(req.target, this).target
200
204
  const reqOptions = getReqOptions(req, query, this)
201
205
  reqOptions.headers = _setHeaders(reqOptions.headers, req)
206
+ const returnType = req._returnType
202
207
  const additionalOptions = getAdditionalOptions(
203
208
  req,
204
209
  this.destination,
205
210
  this.kind,
206
211
  resolvedTarget,
212
+ returnType,
207
213
  this.destinationOptions
208
214
  )
209
215
 
@@ -217,7 +223,7 @@ class RemoteService extends cds.Service {
217
223
  result =
218
224
  typeof query === 'object' && query.SELECT && query.SELECT.one && Array.isArray(result) ? result[0] : result
219
225
 
220
- return cds.env.features.resolve_views === false && typeof query === 'object' ? postProcess(query, result) : result
226
+ return result
221
227
  })
222
228
  }
223
229
 
@@ -226,15 +232,15 @@ class RemoteService extends cds.Service {
226
232
  // - because of that tests/_runtime/remote/__tests__/integration/odata.test.js fails, which relies on the former behavoir of RemoteServices
227
233
  // NOTE: that test would never have worked for RemoteServices bootstrapped from single cds.model, which is always cds.compiled.for.odata
228
234
  // REVISIT: should become obsolete with Universal CSN
229
- set model(m) {
230
- const fn = cds.compile.for.odata
231
- try {
232
- cds.compile.for.odata = m => m
233
- super.model = m
234
- } finally {
235
- cds.compile.for.odata = fn
236
- }
237
- }
235
+ // set model(m) {
236
+ // const fn = cds.compile.for.odata
237
+ // try {
238
+ // cds.compile.for.odata = m => m
239
+ // super.model = m
240
+ // } finally {
241
+ // cds.compile.for.odata = fn
242
+ // }
243
+ // }
238
244
 
239
245
  // Overload .handle in order to resolve projections up to a definition that is known by the remote service instance.
240
246
  // Result is post processed according to the inverse projection in order to reflect the correct result of the original query.
@@ -262,7 +268,7 @@ class RemoteService extends cds.Service {
262
268
  restoreLink(req)
263
269
 
264
270
  // REVISIT: We need to provide target explicitly because it's cached already within ensure_target
265
- const newReq = new cds.Request({ query: q, target: t, headers: req.headers, _resolved: true })
271
+ const newReq = new cds.Request({ query: q, target: t, headers: req.headers, _resolved: true, method: req.method })
266
272
  const result = await super.dispatch(newReq)
267
273
 
268
274
  return postProcess(q, result, this, true)
@@ -5,7 +5,7 @@ const SANITIZE_VALUES = process.env.NODE_ENV === 'production' && cds.env.log.san
5
5
 
6
6
  const { convertV2ResponseData, deepSanitize, convertV2PayloadData } = require('./data')
7
7
 
8
- let _cloudSdkCore
8
+ let _cloudSdk
9
9
 
10
10
  const PPPD = {
11
11
  POST: 1,
@@ -23,12 +23,11 @@ const _sanitizeHeaders = headers => {
23
23
  }
24
24
 
25
25
  const _executeHttpRequest = async ({ requestConfig, destination, destinationOptions, jwt }) => {
26
- const { getDestination, executeHttpRequest } = cloudSdkCore()
26
+ const { executeHttpRequestWithOrigin } = cloudSdk()
27
27
 
28
28
  const destinationName = typeof destination === 'string' && destination
29
29
  if (destinationName) {
30
- destination = await getDestination(destinationName, resolveDestinationOptions(destinationOptions, jwt))
31
- if (!destination) throw new Error(`Cannot resolve destination "${destinationName}"`)
30
+ destination = { destinationName, ...(resolveDestinationOptions(destinationOptions, jwt) || {}) }
32
31
  } else if (destination.forwardAuthToken) {
33
32
  destination = {
34
33
  ...destination,
@@ -44,20 +43,31 @@ const _executeHttpRequest = async ({ requestConfig, destination, destinationOpti
44
43
  }
45
44
 
46
45
  let requestOptions
47
- if (PPPD[requestConfig.method] && cds.env.features.fetch_csrf) {
48
- requestOptions = { fetchCsrfToken: true }
46
+ if (PPPD[requestConfig.method]) {
47
+ // For GET requests, one doesn't need to fetch CSRF tokens.
48
+ // Once we support batch requests (other than autoBatched GET requests),
49
+ // we must check the respective subrequests.
50
+ const csrfRequired = requestConfig._autoBatch ? false : cds.env.features.fetch_csrf === true
51
+ requestOptions = { fetchCsrfToken: csrfRequired }
49
52
  }
50
53
 
51
54
  LOG._debug &&
52
- LOG.debug(`${requestConfig.method} ${destination.url}${requestConfig.url}`, {
55
+ LOG.debug(`${requestConfig.method} ${destination.url || `<${destination.destinationName}>`}${requestConfig.url}`, {
53
56
  headers: _sanitizeHeaders({ ...requestConfig.headers }),
54
57
  data: requestConfig.data && SANITIZE_VALUES ? deepSanitize(requestConfig.data) : requestConfig.data
55
58
  })
56
- return executeHttpRequest(destination, requestConfig, requestOptions)
59
+
60
+ // cloud sdk requires a new mechanism to differentiate the priority of headers
61
+ // "custom" keeps the highest priority as before
62
+ requestConfig = { ...requestConfig, headers: { custom: { ...requestConfig.headers } } }
63
+
64
+ return executeHttpRequestWithOrigin(destination, requestConfig, requestOptions)
57
65
  }
58
66
 
59
- const cloudSdkCore = function () {
60
- return _cloudSdkCore || (_cloudSdkCore = require('@sap-cloud-sdk/core'))
67
+ const cloudSdk = () => {
68
+ if (_cloudSdk) return _cloudSdk
69
+ _cloudSdk = require('@sap-cloud-sdk/http-client')
70
+ return _cloudSdk
61
71
  }
62
72
 
63
73
  const getDestination = (name, credentials) => {
@@ -74,20 +84,18 @@ const getDestination = (name, credentials) => {
74
84
  }
75
85
 
76
86
  /**
77
- * @param {import('./client-types').DestinationOptions} [options]
87
+ * @param {import('@sap-cloud-sdk/connectivity').DestinationFetchOptions} [options]
78
88
  * @param {string} [jwt]
79
- * @returns {import('@sap-cloud-sdk/core').DestinationOptions}
89
+ * @returns {import('@sap-cloud-sdk/connectivity').DestinationFetchOptions}
80
90
  */
81
91
  const resolveDestinationOptions = function (options, jwt) {
82
92
  if (!options && !jwt) return undefined
83
93
 
84
94
  const resolvedOptions = Object.assign({}, options || {})
85
- resolvedOptions.userJwt = jwt
95
+ resolvedOptions.jwt = jwt
86
96
 
87
97
  if (options && options.selectionStrategy) {
88
- resolvedOptions.selectionStrategy = cloudSdkCore().DestinationSelectionStrategies[options.selectionStrategy]
89
- if (!resolvedOptions.selectionStrategy)
90
- throw new Error(`Unsupported destination selection strategy "${options.selectionStrategy}".`)
98
+ resolvedOptions.selectionStrategy = options.selectionStrategy
91
99
  }
92
100
 
93
101
  return resolvedOptions
@@ -165,15 +173,31 @@ function _normalizeMetadata(prefix, data, results) {
165
173
  }
166
174
  return target
167
175
  }
176
+ const _getPurgedRespActionFunc = (data, returnType) => {
177
+ // return type is primitive value or inline/complex type
178
+ if (returnType.kind === 'type' && !returnType.items && Object.values(data).length === 1) {
179
+ // eslint-disable-next-line no-unreachable-loop
180
+ for (const key in data) {
181
+ return data[key]
182
+ }
183
+ }
184
+ return data
185
+ }
168
186
 
169
- const _purgeODataV2 = (data, target, reqHeaders) => {
187
+ const _purgeODataV2 = (data, target, returnType, reqHeaders) => {
170
188
  if (typeof data !== 'object' || !data.d) return data
171
189
 
172
- data = data.d
190
+ data = returnType ? _getPurgedRespActionFunc(data.d, returnType) : data.d
173
191
  const ieee754Compatible = reqHeaders.accept && reqHeaders.accept.includes('IEEE754Compatible=true')
174
192
  const exponentialDecimals = ieee754Compatible && reqHeaders.accept.includes('ExponentialDecimals=true')
175
- const purgedResponse = 'results' in data ? data.results : data
176
- const convertedResponse = convertV2ResponseData(purgedResponse, target, ieee754Compatible, exponentialDecimals)
193
+ const purgedResponse = typeof data === 'object' && 'results' in data ? data.results : data
194
+ const convertedResponse = convertV2ResponseData(
195
+ purgedResponse,
196
+ target,
197
+ returnType,
198
+ ieee754Compatible,
199
+ exponentialDecimals
200
+ )
177
201
  return _normalizeMetadata(/^__/, data, convertedResponse)
178
202
  }
179
203
 
@@ -187,12 +211,15 @@ const _purgeODataV4 = data => {
187
211
  const TYPES_TO_REMOVE = { function: 1, object: 1 }
188
212
  const PROPS_TO_IGNORE = { cause: 1, name: 1 }
189
213
 
190
- const _getSanitizedError = (e, reqOptions, suppressRemoteResponseBody) => {
214
+ const _getSanitizedError = (e, reqOptions, options = { suppressRemoteResponseBody: false, batchRequest: false }) => {
191
215
  e.request = {
192
216
  method: reqOptions.method,
193
217
  url: e.config ? e.config.baseURL + e.config.url : reqOptions.url,
194
218
  headers: e.config ? e.config.headers : reqOptions.headers
195
219
  }
220
+ if (options.batchRequest) {
221
+ e.request.body = reqOptions.data
222
+ }
196
223
 
197
224
  if (e.response) {
198
225
  const response = {
@@ -200,7 +227,7 @@ const _getSanitizedError = (e, reqOptions, suppressRemoteResponseBody) => {
200
227
  statusText: e.response.statusText,
201
228
  headers: e.response.headers
202
229
  }
203
- if (e.response.data && !suppressRemoteResponseBody) {
230
+ if (e.response.data && !options.suppressRemoteResponseBody) {
204
231
  response.body = e.response.data
205
232
  }
206
233
  e.response = response
@@ -236,19 +263,26 @@ const _getSanitizedError = (e, reqOptions, suppressRemoteResponseBody) => {
236
263
  // eslint-disable-next-line complexity
237
264
  const run = async (
238
265
  requestConfig,
239
- { destination, jwt, kind, resolvedTarget, suppressRemoteResponseBody, destinationOptions }
266
+ { destination, jwt, kind, resolvedTarget, returnType, suppressRemoteResponseBody, destinationOptions }
240
267
  ) => {
241
268
  let response
242
269
  try {
243
270
  response = await _executeHttpRequest({ requestConfig, destination, destinationOptions, jwt })
244
271
  } catch (e) {
245
272
  // > axios received status >= 400 -> gateway error
246
- e.message = e.message ? 'Error during request to remote service: ' + e.message : 'Request to remote service failed.'
247
-
248
- const sanitizedError = _getSanitizedError(e, requestConfig, suppressRemoteResponseBody)
273
+ const msg =
274
+ (e.response &&
275
+ e.response.data &&
276
+ e.response.data.error &&
277
+ ((e.response.data.error.message && e.response.data.error.message.value) || e.response.data.error.message)) ||
278
+ e.message
279
+ e.message = msg ? 'Error during request to remote service: \n' + msg : 'Request to remote service failed.'
280
+
281
+ const sanitizedError = _getSanitizedError(e, requestConfig, {
282
+ suppressRemoteResponseBody: suppressRemoteResponseBody
283
+ })
249
284
 
250
- // REVISIT: switch from innererror to reason in cds^6
251
- const err = Object.assign(new Error(e.message), { statusCode: 502, innererror: sanitizedError })
285
+ const err = Object.assign(new Error(e.message), { statusCode: 502, reason: sanitizedError })
252
286
  LOG._warn && LOG.warn(err)
253
287
 
254
288
  throw err
@@ -268,12 +302,13 @@ const run = async (
268
302
  const e = new Error("Received content-type 'text/html' which is not part of accepted content types")
269
303
  e.response = response
270
304
 
271
- const sanitizedError = _getSanitizedError(e, requestConfig, suppressRemoteResponseBody)
305
+ const sanitizedError = _getSanitizedError(e, requestConfig, {
306
+ suppressRemoteResponseBody: suppressRemoteResponseBody
307
+ })
272
308
 
273
- // REVISIT: switch from innererror to reason in cds^6
274
309
  const err = Object.assign(new Error(`Error during request to remote service: ${e.message}`), {
275
310
  statusCode: 502,
276
- innererror: sanitizedError
311
+ reason: sanitizedError
277
312
  })
278
313
 
279
314
  LOG._warn && LOG.warn(err)
@@ -297,27 +332,28 @@ const run = async (
297
332
  response.data = contentJSON
298
333
  }
299
334
  if (responseDataSplitted[1].startsWith('HTTP/1.1 4') || responseDataSplitted[1].startsWith('HTTP/1.1 5')) {
300
- contentJSON.message = contentJSON.message
301
- ? 'Error during request to remote service: ' + contentJSON.message
302
- : 'Request to remote service failed.'
303
- const sanitizedError = _getSanitizedError(contentJSON, requestConfig)
304
-
305
- const err = Object.assign(new Error(contentJSON.message), { statusCode: 502, innererror: sanitizedError })
335
+ const innerError = contentJSON.error || contentJSON
336
+ innerError.status = Number(responseDataSplitted[1].match(/HTTP.*(\d{3})/m)[1])
337
+ innerError.response = response
338
+ const sanitizedError = _getSanitizedError(innerError, requestConfig, { batchRequest: true })
339
+ const err = Object.assign(new Error('Request to remote service failed.'), {
340
+ statusCode: 502,
341
+ reason: sanitizedError
342
+ })
306
343
 
307
344
  LOG._warn && LOG.warn(err)
308
345
 
309
- // REVISIT: switch from innererror to reason in cds^6
310
346
  throw err
311
347
  }
312
348
  }
313
349
 
314
350
  if (kind === 'odata-v4') return _purgeODataV4(response.data)
315
- if (kind === 'odata-v2') return _purgeODataV2(response.data, resolvedTarget, requestConfig.headers)
351
+ if (kind === 'odata-v2') return _purgeODataV2(response.data, resolvedTarget, returnType, requestConfig.headers)
316
352
  if (kind === 'odata') {
317
353
  if (typeof response.data !== 'object') return response.data
318
354
  // try to guess if we need to purge v2 or v4
319
355
  if (response.data.d) {
320
- return _purgeODataV2(response.data, resolvedTarget, requestConfig.headers)
356
+ return _purgeODataV2(response.data, resolvedTarget, returnType, requestConfig.headers)
321
357
  }
322
358
  return _purgeODataV4(response.data)
323
359
  }
@@ -335,8 +371,10 @@ const getJwt = req => {
335
371
  return null
336
372
  }
337
373
 
338
- const _cqnToReqOptions = (query, kind, model, target) => {
339
- const queryObject = cds.odata.urlify(query, { kind, model })
374
+ const _cqnToReqOptions = (query, service, req) => {
375
+ const { kind, model } = service
376
+ const method = req.method
377
+ const queryObject = cds.odata.urlify(query, { kind, model, method })
340
378
  const reqOptions = {
341
379
  method: queryObject.method,
342
380
  url: queryObject.path
@@ -345,7 +383,7 @@ const _cqnToReqOptions = (query, kind, model, target) => {
345
383
  .replace(/ \)/g, ')')
346
384
  }
347
385
  if (queryObject.method !== 'GET' && queryObject.method !== 'HEAD') {
348
- reqOptions.data = kind === 'odata-v2' ? convertV2PayloadData(queryObject.body, target) : queryObject.body
386
+ reqOptions.data = kind === 'odata-v2' ? convertV2PayloadData(queryObject.body, req.target) : queryObject.body
349
387
  }
350
388
  return reqOptions
351
389
  }
@@ -390,7 +428,7 @@ const _hasHeader = (headers, header) =>
390
428
  const getReqOptions = (req, query, service) => {
391
429
  const reqOptions =
392
430
  typeof query === 'object'
393
- ? _cqnToReqOptions(query, service.kind, service.model, req.target)
431
+ ? _cqnToReqOptions(query, service, req)
394
432
  : typeof query === 'string'
395
433
  ? _stringToReqOptions(query, req.data, req.target)
396
434
  : _pathToReqOptions(req.method, req.path, req.data, req.target)
@@ -450,9 +488,9 @@ const getReqOptions = (req, query, service) => {
450
488
  return reqOptions
451
489
  }
452
490
 
453
- const getAdditionalOptions = (req, destination, kind, resolvedTarget, destinationOptions) => {
491
+ const getAdditionalOptions = (req, destination, kind, resolvedTarget, returnType, destinationOptions) => {
454
492
  const jwt = getJwt(req)
455
- const additionalOptions = { destination, kind, resolvedTarget, destinationOptions }
493
+ const additionalOptions = { destination, kind, resolvedTarget, returnType, destinationOptions }
456
494
  if (jwt) additionalOptions.jwt = jwt
457
495
  return additionalOptions
458
496
  }
@@ -22,8 +22,10 @@ const DataTypeOData = {
22
22
  Time: 'cds.TimeOfDay'
23
23
  }
24
24
 
25
- const _convertData = (data, target, convertValueFn) => {
26
- const _convertRecordFn = _getConvertRecordFn(target, convertValueFn)
25
+ const _convertData = (data, target, convertValueFn, returnType) => {
26
+ const _convertRecordFn = returnType
27
+ ? _convertActionFuncResponse(returnType, convertValueFn)
28
+ : _getConvertRecordFn(target, convertValueFn)
27
29
  if (Array.isArray(data)) {
28
30
  return data.map(_convertRecordFn)
29
31
  }
@@ -52,6 +54,16 @@ const _getConvertRecordFn = (target, convertValueFn) => record => {
52
54
  return record
53
55
  }
54
56
 
57
+ const _convertActionFuncResponse = (returnType, convertValueFn) => data => {
58
+ // return type is entity/complex type or array of entities/complex types
59
+ if (returnType.elements || (returnType.items && returnType.items.elements)) {
60
+ const _convertRecordFn = _getConvertRecordFn(returnType.items || returnType, convertValueFn)
61
+ return _convertRecordFn(data)
62
+ }
63
+ // return type is primitive type/array of primitive types
64
+ return convertValueFn(data, returnType.items || returnType)
65
+ }
66
+
55
67
  // eslint-disable-next-line complexity
56
68
  const _convertValue = (ieee754Compatible, exponentialDecimals) => (value, element) => {
57
69
  if (value == null) {
@@ -151,9 +163,9 @@ const _elementType = element => {
151
163
  return type
152
164
  }
153
165
 
154
- const convertV2ResponseData = (data, target, ieee754Compatible, exponentialDecimals) => {
155
- if (!target || !target.elements) return data
156
- return _convertData(data, target, _convertValue(ieee754Compatible, exponentialDecimals))
166
+ const convertV2ResponseData = (data, target, returnType, ieee754Compatible, exponentialDecimals) => {
167
+ if (!((target && target.elements) || returnType)) return data
168
+ return _convertData(data, target, _convertValue(ieee754Compatible, exponentialDecimals), returnType)
157
169
  }
158
170
 
159
171
  const convertV2PayloadData = (data, target) => {
@@ -171,8 +183,13 @@ const deepSanitize = arg => {
171
183
  return '***'
172
184
  }
173
185
 
186
+ const hasAliasedColumns = (column = {}) => {
187
+ return column.as || (column.expand && column.expand.some(hasAliasedColumns))
188
+ }
189
+
174
190
  module.exports = {
175
191
  convertV2ResponseData,
176
192
  convertV2PayloadData,
177
- deepSanitize
193
+ deepSanitize,
194
+ hasAliasedColumns
178
195
  }
@@ -99,33 +99,34 @@ module.exports = class SQLiteDatabase extends DatabaseService {
99
99
  }
100
100
  }
101
101
 
102
+ getDbUrl(tenant) {
103
+ const credentials = this.options.credentials || this.options || {}
104
+ let dbUrl = credentials.database || credentials.url || credentials.host || ':memory:'
105
+
106
+ if (tenant && dbUrl.endsWith('.db')) {
107
+ dbUrl = dbUrl.split('.db')[0] + '_' + tenant + '.db'
108
+ }
109
+ return dbUrl
110
+ }
111
+
102
112
  /*
103
113
  * connection
104
114
  */
105
115
  async acquire(arg) {
106
116
  // in non-multi-tenant scenarios, the default db should be returned regardless of arg
107
- let tenant = 'anonymous'
108
117
  const isMultitenant = 'multiTenant' in this.options ? this.options.multiTenant : cds.env.requires.multitenancy
109
118
  // REVISIT: there should already be compat for the multitenancy flag, why is it not working here?
110
- if (isMultitenant && arg) {
111
- if (typeof arg === 'string') tenant = arg
112
- else tenant = arg.tenant || (arg.user && arg.user.tenant) || tenant // > REVISIT: remove fallback arg.user.tenant with cds^6
113
- }
114
-
119
+ // REVISIT: remove fallback arg.user.tenant with cds^6
120
+ const tenant = isMultitenant && arg && (typeof arg === 'string' ? arg : arg.tenant || (arg.user && arg.user.tenant))
115
121
  let dbc = this.dbcs.get(tenant)
116
122
  if (!dbc) {
117
- const credentials = this.options.credentials || this.options || {}
118
- let dbUrl = credentials.database || credentials.url || credentials.host || ':memory:'
119
-
120
- if (isMultitenant && dbUrl.endsWith('.db')) {
121
- dbUrl = dbUrl.split('.db')[0] + '_' + tenant + '.db'
122
- }
123
+ const dbUrl = this.getDbUrl(tenant)
123
124
 
124
125
  dbc = await _new(dbUrl)
125
126
 
126
127
  dbc._queued = []
127
128
 
128
- if (cds.env.features._db_foreign_key_constraints) {
129
+ if (cds.env.features.assert_integrity && cds.env.features.assert_integrity_type == 'DB') {
129
130
  await new Promise((resolve, reject) => {
130
131
  dbc.exec('PRAGMA foreign_keys = ON', err => {
131
132
  if (err) reject(err)
@@ -28,8 +28,10 @@ const _convert = (refEntries, req) => {
28
28
  // only check refs in format {ref: ['assoc', 'id']}
29
29
  continue
30
30
  }
31
+
31
32
  const element = req.target.elements[refEntry.ref[0]]
32
33
  if (!element || !element.is2one) return
34
+
33
35
  _convertRefForAssocToOneManaged(element, refEntry)
34
36
  }
35
37
  }
@@ -34,6 +34,7 @@ class CustomSelectBuilder extends SelectBuilder {
34
34
  }
35
35
 
36
36
  _forUpdate() {}
37
+ _forShareLock() {}
37
38
  }
38
39
 
39
40
  module.exports = CustomSelectBuilder
@@ -8,6 +8,7 @@ const { Readable } = require('stream')
8
8
  const cds = require('../cds')
9
9
  const LOG = cds.log('sqlite|db|sql')
10
10
  // && {_debug:true, debug(sql){ cds._debug && console.log(sql+';\n') }} //> please keep that for debugging stakeholder tests
11
+ const coloredTxCommands = require('../db/utils/coloredTxCommands')
11
12
  const { inspect } = require('util')
12
13
 
13
14
  const SANITIZE_VALUES = process.env.NODE_ENV === 'production' && cds.env.log.sanitize_values !== false
@@ -26,14 +27,6 @@ const _captureStack = DEBUG
26
27
  }
27
28
  : () => undefined
28
29
 
29
- /*
30
- * helpers
31
- */
32
- const _colored = {
33
- BEGIN: '\x1b[1m\x1b[33mBEGIN\x1b[0m',
34
- COMMIT: '\x1b[1m\x1b[32mCOMMIT\x1b[0m',
35
- ROLLBACK: '\x1b[1m\x1b[91mROLLBACK\x1b[0m'
36
- }
37
30
  const _augmented = (err, sql, values, o) => {
38
31
  err.query = sql
39
32
  if (values) err.values = SANITIZE_VALUES ? ['***'] : values
@@ -43,7 +36,8 @@ const _augmented = (err, sql, values, o) => {
43
36
  }
44
37
 
45
38
  function _executeSimpleSQL(dbc, sql, values) {
46
- LOG._debug && LOG.debug(_colored[sql] || sql, Array.isArray(values) ? (SANITIZE_VALUES ? ['***'] : values) : '')
39
+ LOG._debug &&
40
+ LOG.debug(coloredTxCommands[sql] || sql, Array.isArray(values) ? (SANITIZE_VALUES ? ['***'] : values) : '')
47
41
 
48
42
  return new Promise((resolve, reject) => {
49
43
  const o = _captureStack()