@sap/cds 5.9.6 → 6.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (381) hide show
  1. package/CHANGELOG.md +266 -20
  2. package/apis/services.d.ts +1 -1
  3. package/app/fiori/preview.js +2 -6
  4. package/app/index.js +3 -3
  5. package/bin/build/buildTaskEngine.js +17 -15
  6. package/bin/build/buildTaskFactory.js +29 -19
  7. package/bin/build/buildTaskHandler.js +27 -11
  8. package/bin/build/buildTaskProvider.js +2 -4
  9. package/bin/build/buildTaskProviderFactory.js +11 -16
  10. package/bin/build/constants.js +14 -6
  11. package/bin/build/csv-reader.js +2 -1
  12. package/bin/build/index.js +12 -18
  13. package/bin/build/provider/buildTaskHandlerEdmx.js +3 -39
  14. package/bin/build/provider/buildTaskHandlerFeatureToggles.js +149 -0
  15. package/bin/build/provider/buildTaskHandlerInternal.js +2 -3
  16. package/bin/build/provider/buildTaskProviderInternal.js +108 -239
  17. package/bin/build/provider/fiori/index.js +2 -2
  18. package/bin/build/provider/hana/2migration.js +11 -11
  19. package/bin/build/provider/hana/2tabledata.js +3 -3
  20. package/bin/build/provider/hana/index.js +89 -99
  21. package/bin/build/provider/hana/migrationtable.js +4 -3
  22. package/bin/build/provider/java/index.js +101 -0
  23. package/bin/build/provider/java-cf/index.js +1 -101
  24. package/bin/build/provider/mtx/index.js +90 -53
  25. package/bin/build/provider/mtx/resourcesTarBuilder.js +68 -0
  26. package/bin/build/provider/mtx-sidecar/index.js +80 -0
  27. package/bin/build/provider/node-cf/index.js +1 -308
  28. package/bin/build/provider/nodejs/index.js +189 -0
  29. package/bin/build/util.js +19 -31
  30. package/bin/cds.js +5 -3
  31. package/bin/deploy/to-hana/cfUtil.js +31 -6
  32. package/bin/deploy/to-hana/gitUtil.js +5 -3
  33. package/bin/deploy/to-hana/hana.js +9 -10
  34. package/bin/{build → deploy/to-hana}/mtaUtil.js +10 -9
  35. package/bin/mtx/in-cds.js +19 -7
  36. package/bin/serve.js +56 -21
  37. package/bin/utils/log.js +13 -30
  38. package/bin/version.js +5 -4
  39. package/common.cds +61 -16
  40. package/lib/compile/cdsc.js +3 -2
  41. package/lib/compile/etc/_localized.js +15 -14
  42. package/lib/compile/for/drafts.js +3 -4
  43. package/lib/compile/for/java.js +13 -10
  44. package/lib/compile/for/nodejs.js +8 -8
  45. package/lib/compile/for/odata.js +7 -12
  46. package/lib/compile/for/sql.js +5 -6
  47. package/lib/compile/index.js +5 -4
  48. package/lib/compile/load.js +9 -11
  49. package/lib/compile/minify.js +8 -5
  50. package/lib/compile/parse.js +4 -2
  51. package/lib/compile/resolve.js +18 -15
  52. package/lib/compile/to/edm.js +0 -1
  53. package/lib/compile/to/gql.js +3 -2
  54. package/lib/compile/to/json.js +24 -17
  55. package/lib/connect/bindings.js +3 -2
  56. package/lib/connect/index.js +5 -5
  57. package/lib/core/classes.js +74 -2
  58. package/lib/core/entities.js +52 -3
  59. package/lib/core/reflect.js +2 -1
  60. package/lib/deploy.js +11 -8
  61. package/lib/env/defaults.js +4 -3
  62. package/lib/env/index.js +71 -31
  63. package/lib/env/presets.js +1 -14
  64. package/lib/env/requires.js +70 -20
  65. package/lib/env/serviceBindings.js +147 -0
  66. package/lib/i18n/localize.js +22 -23
  67. package/lib/index.js +148 -144
  68. package/lib/log/errors.js +55 -12
  69. package/lib/log/format/kibana.js +1 -1
  70. package/lib/log/index.js +4 -0
  71. package/lib/ql/SELECT.js +7 -2
  72. package/lib/ql/Whereable.js +8 -2
  73. package/lib/ql/index.js +2 -2
  74. package/lib/req/assert.js +71 -0
  75. package/lib/req/cds-context.js +38 -70
  76. package/lib/req/context.js +34 -21
  77. package/lib/req/request.js +12 -18
  78. package/lib/req/response.js +6 -2
  79. package/lib/req/user.js +30 -22
  80. package/lib/serve/Service-api.js +17 -12
  81. package/lib/serve/Service-dispatch.js +5 -9
  82. package/lib/serve/Service-methods.js +4 -3
  83. package/lib/serve/Transaction.js +24 -21
  84. package/lib/serve/adapters.js +15 -5
  85. package/lib/serve/factory.js +23 -20
  86. package/lib/serve/index.js +51 -54
  87. package/lib/utils/axios.js +8 -12
  88. package/lib/utils/index.js +3 -3
  89. package/lib/utils/resources/index.js +1 -44
  90. package/lib/utils/resources/tar.js +2 -1
  91. package/lib/utils/tests.js +13 -15
  92. package/libx/_runtime/.eslintrc +1 -1
  93. package/libx/_runtime/audit/Service.js +6 -4
  94. package/libx/_runtime/audit/generic/personal/access.js +19 -43
  95. package/libx/_runtime/audit/generic/personal/index.js +40 -34
  96. package/libx/_runtime/audit/generic/personal/modification.js +11 -9
  97. package/libx/_runtime/audit/generic/personal/utils.js +13 -6
  98. package/libx/_runtime/audit/utils/v2.js +6 -3
  99. package/libx/_runtime/auth/index.js +71 -66
  100. package/libx/_runtime/auth/strategies/JWT.js +3 -2
  101. package/libx/_runtime/auth/strategies/mock.js +54 -53
  102. package/libx/_runtime/auth/strategies/xssecUtils.js +3 -4
  103. package/libx/_runtime/auth/strategies/xsuaa.js +3 -2
  104. package/libx/_runtime/auth/utils.js +2 -15
  105. package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +128 -42
  106. package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +6 -3
  107. package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +93 -73
  108. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +10 -45
  109. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +5 -9
  110. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +9 -5
  111. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +4 -2
  112. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +60 -53
  113. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +1 -1
  114. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +15 -21
  115. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +8 -15
  116. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/expandToCQN.js +29 -41
  117. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/index.js +1 -4
  118. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/readToCQN.js +13 -13
  119. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/selectToCQN.js +0 -7
  120. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/utils.js +24 -1
  121. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/edm/EdmEntityContainer.js +1 -1
  122. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/UriHelper.js +4 -3
  123. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/utils/PrimitiveValueDecoder.js +4 -5
  124. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/utils/ValueConverter.js +4 -3
  125. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/validator/ValueValidator.js +5 -3
  126. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/core/ResponseHeaderSetter.js +2 -0
  127. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/DebugSerializingCommand.js +1 -1
  128. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/PresetResponseHeadersCommand.js +1 -1
  129. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/SerializingCommand.js +1 -1
  130. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/SetResponseHeadersCommand.js +1 -1
  131. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/ContextURLFactory.js +3 -2
  132. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/ErrorJsonSerializer.js +3 -1
  133. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/SerializerFactory.js +1 -0
  134. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/TrustedResourceJsonSerializer.js +3 -3
  135. package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +36 -25
  136. package/libx/_runtime/cds-services/adapter/odata-v4/utils/handlerUtils.js +100 -91
  137. package/libx/_runtime/cds-services/adapter/odata-v4/utils/metaInfo.js +382 -0
  138. package/libx/_runtime/cds-services/adapter/odata-v4/utils/oDataConfiguration.js +1 -4
  139. package/libx/_runtime/cds-services/adapter/odata-v4/utils/omitValues.js +5 -6
  140. package/libx/_runtime/cds-services/adapter/odata-v4/utils/readAfterWrite.js +77 -21
  141. package/libx/_runtime/cds-services/adapter/odata-v4/utils/request.js +3 -11
  142. package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +91 -69
  143. package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +27 -6
  144. package/libx/_runtime/cds-services/adapter/rest/utils/validation-checks.js +7 -17
  145. package/libx/_runtime/cds-services/services/Service.js +17 -76
  146. package/libx/_runtime/cds-services/services/utils/columns.js +6 -4
  147. package/libx/_runtime/cds-services/services/utils/compareJson.js +1 -53
  148. package/libx/_runtime/cds-services/services/utils/differ.js +15 -19
  149. package/libx/_runtime/cds-services/util/assert.js +107 -34
  150. package/libx/_runtime/cds.js +1 -31
  151. package/libx/_runtime/common/aspects/Association.js +40 -54
  152. package/libx/_runtime/common/aspects/any.js +61 -6
  153. package/libx/_runtime/common/aspects/entity.js +19 -79
  154. package/libx/_runtime/common/composition/data.js +2 -2
  155. package/libx/_runtime/common/composition/delete.js +16 -18
  156. package/libx/_runtime/common/composition/tree.js +10 -10
  157. package/libx/_runtime/common/composition/update.js +3 -2
  158. package/libx/_runtime/common/constants/events.js +15 -0
  159. package/libx/_runtime/common/error/entry.js +9 -3
  160. package/libx/_runtime/common/error/frontend.js +13 -19
  161. package/libx/_runtime/common/error/index.js +8 -3
  162. package/libx/_runtime/common/generic/auth/capabilities.js +2 -1
  163. package/libx/_runtime/common/generic/auth/constants.js +1 -4
  164. package/libx/_runtime/common/generic/auth/requires.js +1 -1
  165. package/libx/_runtime/common/generic/auth/restrict.js +12 -28
  166. package/libx/_runtime/common/generic/auth/restrictions.js +12 -4
  167. package/libx/_runtime/common/generic/auth/utils.js +2 -1
  168. package/libx/_runtime/common/generic/crud.js +9 -60
  169. package/libx/_runtime/common/generic/etag.js +41 -7
  170. package/libx/_runtime/common/generic/input.js +128 -66
  171. package/libx/_runtime/common/generic/paging.js +9 -3
  172. package/libx/_runtime/common/generic/put.js +2 -2
  173. package/libx/_runtime/common/generic/sorting.js +11 -4
  174. package/libx/_runtime/common/generic/temporal.js +0 -5
  175. package/libx/_runtime/common/i18n/messages.properties +2 -1
  176. package/libx/_runtime/common/utils/binary.js +69 -0
  177. package/libx/_runtime/common/utils/cqn.js +39 -14
  178. package/libx/_runtime/common/utils/cqn2cqn4sql.js +93 -59
  179. package/libx/_runtime/common/utils/csn.js +87 -85
  180. package/libx/_runtime/common/utils/dollar.js +8 -7
  181. package/libx/_runtime/common/utils/draft.js +1 -1
  182. package/libx/_runtime/common/utils/foreignKeyPropagations.js +23 -7
  183. package/libx/_runtime/common/utils/generateOnCond.js +2 -1
  184. package/libx/_runtime/common/utils/keys.js +30 -13
  185. package/libx/_runtime/common/utils/postProcessing.js +6 -1
  186. package/libx/_runtime/common/utils/quotingStyles.js +0 -23
  187. package/libx/_runtime/common/utils/resolveStructured.js +23 -26
  188. package/libx/_runtime/common/utils/resolveView.js +4 -1
  189. package/libx/_runtime/common/utils/rewriteAsterisks.js +3 -0
  190. package/libx/_runtime/common/utils/search2cqn4sql.js +4 -13
  191. package/libx/_runtime/common/utils/searchToLike.js +9 -13
  192. package/libx/_runtime/common/utils/streamProp.js +35 -0
  193. package/libx/_runtime/common/utils/structured.js +12 -18
  194. package/libx/_runtime/common/utils/template.js +3 -5
  195. package/libx/_runtime/common/utils/templateProcessor.js +22 -14
  196. package/libx/_runtime/common/utils/unionCqnTemplate.js +4 -14
  197. package/libx/_runtime/db/Service.js +2 -1
  198. package/libx/_runtime/db/expand/expand-v2.js +2 -2
  199. package/libx/_runtime/db/expand/expandCQNToJoin.js +7 -6
  200. package/libx/_runtime/db/generic/input.js +14 -17
  201. package/libx/_runtime/db/generic/integrity.js +1 -2
  202. package/libx/_runtime/db/generic/update.js +14 -1
  203. package/libx/_runtime/db/query/read.js +0 -1
  204. package/libx/_runtime/db/query/update.js +1 -1
  205. package/libx/_runtime/db/sql-builder/BaseBuilder.js +1 -1
  206. package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +5 -31
  207. package/libx/_runtime/db/sql-builder/InsertBuilder.js +1 -1
  208. package/libx/_runtime/db/sql-builder/ReferenceBuilder.js +0 -9
  209. package/libx/_runtime/db/sql-builder/SelectBuilder.js +11 -10
  210. package/libx/_runtime/db/sql-builder/UpdateBuilder.js +2 -2
  211. package/libx/_runtime/db/sql-builder/annotations.js +1 -2
  212. package/libx/_runtime/db/utils/coloredTxCommands.js +5 -0
  213. package/libx/_runtime/db/utils/columns.js +1 -1
  214. package/libx/_runtime/db/utils/propagateForeignKeys.js +10 -2
  215. package/libx/_runtime/extensibility/activate.js +69 -0
  216. package/libx/_runtime/extensibility/add.js +41 -0
  217. package/libx/_runtime/extensibility/addExtension.js +68 -0
  218. package/libx/_runtime/extensibility/defaults.js +39 -0
  219. package/libx/_runtime/extensibility/{uiflex/handler → handler}/transformREAD.js +0 -0
  220. package/libx/_runtime/extensibility/{uiflex/handler → handler}/transformRESULT.js +2 -2
  221. package/libx/_runtime/extensibility/{uiflex/handler → handler}/transformWRITE.js +2 -2
  222. package/libx/_runtime/extensibility/push.js +61 -0
  223. package/libx/_runtime/extensibility/service.js +21 -0
  224. package/libx/_runtime/extensibility/{uiflex/utils.js → utils.js} +39 -3
  225. package/libx/_runtime/extensibility/validation.js +53 -0
  226. package/libx/_runtime/extensibility/views.js +12 -0
  227. package/libx/_runtime/fiori/generic/activate.js +6 -4
  228. package/libx/_runtime/fiori/generic/before.js +17 -29
  229. package/libx/_runtime/fiori/generic/cancel.js +2 -4
  230. package/libx/_runtime/fiori/generic/delete.js +2 -4
  231. package/libx/_runtime/fiori/generic/edit.js +3 -7
  232. package/libx/_runtime/fiori/generic/index.js +31 -0
  233. package/libx/_runtime/fiori/generic/new.js +2 -4
  234. package/libx/_runtime/fiori/generic/patch.js +4 -8
  235. package/libx/_runtime/fiori/generic/prepare.js +2 -4
  236. package/libx/_runtime/fiori/generic/read.js +137 -162
  237. package/libx/_runtime/fiori/generic/readOverDraft.js +10 -4
  238. package/libx/_runtime/fiori/utils/handler.js +10 -5
  239. package/libx/_runtime/fiori/utils/where.js +1 -4
  240. package/libx/_runtime/hana/Service.js +14 -7
  241. package/libx/_runtime/hana/customBuilder/CustomSelectBuilder.js +1 -1
  242. package/libx/_runtime/hana/dynatrace.js +2 -2
  243. package/libx/_runtime/hana/localized.js +7 -6
  244. package/libx/_runtime/hana/pool.js +9 -6
  245. package/libx/_runtime/hana/search.js +2 -3
  246. package/libx/_runtime/hana/{searchToContains.js → search2Contains.js} +5 -2
  247. package/libx/_runtime/hana/search2cqn4sql.js +20 -17
  248. package/libx/_runtime/index.js +2 -6
  249. package/libx/_runtime/messaging/AMQPWebhookMessaging.js +11 -2
  250. package/libx/_runtime/messaging/common-utils/AMQPClient.js +4 -3
  251. package/libx/_runtime/messaging/common-utils/appId.js +9 -0
  252. package/libx/_runtime/messaging/common-utils/authorizedRequest.js +2 -18
  253. package/libx/_runtime/messaging/common-utils/connections.js +1 -1
  254. package/libx/_runtime/messaging/enterprise-messaging-shared.js +2 -2
  255. package/libx/_runtime/messaging/enterprise-messaging-utils/EMManagement.js +305 -231
  256. package/libx/_runtime/messaging/enterprise-messaging-utils/cloudEvents.js +2 -2
  257. package/libx/_runtime/messaging/enterprise-messaging-utils/options-management.js +15 -8
  258. package/libx/_runtime/messaging/enterprise-messaging-utils/options-messaging.js +57 -14
  259. package/libx/_runtime/messaging/enterprise-messaging.js +14 -19
  260. package/libx/_runtime/messaging/file-based.js +2 -1
  261. package/libx/_runtime/messaging/http-utils/token.js +18 -6
  262. package/libx/_runtime/messaging/message-queuing-utils/options-management.js +22 -12
  263. package/libx/_runtime/messaging/message-queuing-utils/options-messaging.js +27 -14
  264. package/libx/_runtime/messaging/message-queuing.js +138 -85
  265. package/libx/_runtime/messaging/outbox/utils.js +13 -7
  266. package/libx/_runtime/messaging/redis-messaging.js +0 -1
  267. package/libx/_runtime/messaging/service.js +4 -1
  268. package/libx/_runtime/remote/Service.js +24 -18
  269. package/libx/_runtime/remote/utils/client.js +84 -46
  270. package/libx/_runtime/remote/utils/data.js +23 -6
  271. package/libx/_runtime/sqlite/Service.js +14 -13
  272. package/libx/_runtime/sqlite/convertAssocToOneManaged.js +2 -0
  273. package/libx/_runtime/sqlite/customBuilder/CustomSelectBuilder.js +1 -0
  274. package/libx/_runtime/sqlite/execute.js +3 -9
  275. package/libx/_runtime/types/api.js +23 -11
  276. package/libx/common/utils/ucsn.js +15 -9
  277. package/libx/odata/afterburner.js +109 -29
  278. package/libx/odata/cqn2odata.js +48 -9
  279. package/libx/odata/grammar.pegjs +261 -157
  280. package/libx/odata/index.js +21 -9
  281. package/libx/odata/parseToCqn.js +8 -5
  282. package/libx/odata/parser.js +1 -1
  283. package/libx/odata/utils.js +13 -3
  284. package/libx/rest/RestAdapter.js +173 -113
  285. package/libx/rest/RestRequest.js +3 -2
  286. package/libx/rest/middleware/create.js +8 -6
  287. package/libx/rest/middleware/delete.js +6 -13
  288. package/libx/rest/middleware/error.js +1 -1
  289. package/libx/rest/middleware/input.js +6 -6
  290. package/libx/rest/middleware/operation.js +8 -3
  291. package/libx/rest/middleware/parse.js +3 -3
  292. package/libx/rest/middleware/payload.js +12 -0
  293. package/libx/rest/middleware/read.js +12 -2
  294. package/libx/rest/middleware/update.js +3 -3
  295. package/package.json +4 -6
  296. package/server.js +3 -44
  297. package/srv/extensibility-service.cds +56 -0
  298. package/srv/extensibility-service.js +1 -0
  299. package/srv/extensions.cds +8 -0
  300. package/srv/model-provider.cds +59 -0
  301. package/srv/model-provider.js +163 -0
  302. package/srv/mtx.cds +2 -0
  303. package/srv/mtx.js +22 -0
  304. package/srv/outbox.cds +2 -0
  305. package/tasks/enterprise-messaging-deploy.js +19 -12
  306. package/lib/serve/Service-compat.js +0 -36
  307. package/libx/_runtime/audit/generic/personal/constants.js +0 -4
  308. package/libx/_runtime/auth/strategies/dwc.js +0 -45
  309. package/libx/_runtime/cds-services/adapter/odata-v4/utils/dispatcherUtils.js +0 -56
  310. package/libx/_runtime/cds-services/adapter/rest/Rest.js +0 -183
  311. package/libx/_runtime/cds-services/adapter/rest/RestRequest.js +0 -67
  312. package/libx/_runtime/cds-services/adapter/rest/handlers/create.js +0 -82
  313. package/libx/_runtime/cds-services/adapter/rest/handlers/delete.js +0 -39
  314. package/libx/_runtime/cds-services/adapter/rest/handlers/operation.js +0 -63
  315. package/libx/_runtime/cds-services/adapter/rest/handlers/read.js +0 -52
  316. package/libx/_runtime/cds-services/adapter/rest/handlers/update.js +0 -81
  317. package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/index.js +0 -56
  318. package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/utils.js +0 -33
  319. package/libx/_runtime/cds-services/adapter/rest/to.js +0 -8
  320. package/libx/_runtime/cds-services/adapter/rest/utils/binary.js +0 -50
  321. package/libx/_runtime/cds-services/adapter/rest/utils/data.js +0 -117
  322. package/libx/_runtime/cds-services/adapter/rest/utils/header-checks.js +0 -14
  323. package/libx/_runtime/cds-services/adapter/rest/utils/key-value-utils.js +0 -30
  324. package/libx/_runtime/cds-services/adapter/rest/utils/parse-url.js +0 -250
  325. package/libx/_runtime/cds-services/adapter/rest/utils/result.js +0 -26
  326. package/libx/_runtime/cds-services/services/utils/handlerUtils.js +0 -200
  327. package/libx/_runtime/common/aspects/utils.js +0 -152
  328. package/libx/_runtime/common/toggles/handler.js +0 -21
  329. package/libx/_runtime/common/utils/extensibilityUtils.js +0 -18
  330. package/libx/_runtime/extensibility/mps/index.js +0 -5
  331. package/libx/_runtime/extensibility/mps/service.js +0 -111
  332. package/libx/_runtime/extensibility/mps/tar.js +0 -42
  333. package/libx/_runtime/extensibility/mps/utils.js +0 -11
  334. package/libx/_runtime/extensibility/uiflex/index.js +0 -54
  335. package/libx/_runtime/extensibility/uiflex/service.js +0 -276
  336. package/libx/_runtime/messaging/common-utils/naming-conventions.js +0 -20
  337. package/libx/_runtime/remote/utils/client-types.d.ts +0 -7
  338. package/libx/gql/GraphQLAdapter.js +0 -33
  339. package/libx/gql/constants/adapter.js +0 -69
  340. package/libx/gql/constants/cds.js +0 -18
  341. package/libx/gql/constants/graphql.js +0 -33
  342. package/libx/gql/readme.md +0 -1
  343. package/libx/gql/resolvers/crud/create.js +0 -20
  344. package/libx/gql/resolvers/crud/delete.js +0 -29
  345. package/libx/gql/resolvers/crud/index.js +0 -6
  346. package/libx/gql/resolvers/crud/read.js +0 -30
  347. package/libx/gql/resolvers/crud/update.js +0 -42
  348. package/libx/gql/resolvers/crud/utils/index.js +0 -36
  349. package/libx/gql/resolvers/field.js +0 -5
  350. package/libx/gql/resolvers/index.js +0 -7
  351. package/libx/gql/resolvers/mutation.js +0 -23
  352. package/libx/gql/resolvers/parse/ast/enrich.js +0 -52
  353. package/libx/gql/resolvers/parse/ast/fragment.js +0 -11
  354. package/libx/gql/resolvers/parse/ast/fromObject.js +0 -39
  355. package/libx/gql/resolvers/parse/ast/index.js +0 -3
  356. package/libx/gql/resolvers/parse/ast/meta.js +0 -4
  357. package/libx/gql/resolvers/parse/ast/variable.js +0 -7
  358. package/libx/gql/resolvers/parse/ast2cqn/columns.js +0 -44
  359. package/libx/gql/resolvers/parse/ast2cqn/entries.js +0 -31
  360. package/libx/gql/resolvers/parse/ast2cqn/index.js +0 -8
  361. package/libx/gql/resolvers/parse/ast2cqn/limit.js +0 -6
  362. package/libx/gql/resolvers/parse/ast2cqn/orderBy.js +0 -24
  363. package/libx/gql/resolvers/parse/ast2cqn/utils/index.js +0 -3
  364. package/libx/gql/resolvers/parse/ast2cqn/where.js +0 -70
  365. package/libx/gql/resolvers/parse/utils/index.js +0 -8
  366. package/libx/gql/resolvers/query.js +0 -13
  367. package/libx/gql/resolvers/root.js +0 -34
  368. package/libx/gql/schema/generate.js +0 -18
  369. package/libx/gql/schema/index.js +0 -5
  370. package/libx/gql/schema/mutation.js +0 -76
  371. package/libx/gql/schema/query.js +0 -108
  372. package/libx/gql/schema/typeDefMap.js +0 -45
  373. package/libx/gql/schema/utils/index.js +0 -54
  374. package/libx/gql/utils/index.js +0 -12
  375. package/libx/rest/middleware/auth.js +0 -20
  376. package/libx/rest/middleware/content.js +0 -19
  377. package/srv/flex.cds +0 -21
  378. package/srv/flex.js +0 -1
  379. package/srv/mps.cds +0 -23
  380. package/srv/mps.js +0 -1
  381. package/srv/outbox.js +0 -0
@@ -51,15 +51,6 @@ class ReferenceBuilder extends BaseBuilder {
51
51
  this._outputObj.sql.push('CAST', '(')
52
52
  }
53
53
 
54
- // REVISIT: compat for legacy ref: "['foo as bar']" -> remove with cds^6
55
- if (this._obj.ref.length === 1 && typeof this._obj.ref[0] === 'string') {
56
- const matched = this._obj.ref[0].match(/(\S*)\s{1,}as\s{1,}(\S*)/i)
57
- if (matched) {
58
- this._obj.ref = [matched[1]]
59
- this._obj.as = matched[2].replace(/^"/, '').replace(/"$/, '')
60
- }
61
- }
62
-
63
54
  if (this._obj.param) {
64
55
  this._parseParamReference(this._obj.ref)
65
56
  } else {
@@ -1,5 +1,3 @@
1
- const cds = require('../../cds')
2
-
3
1
  const BaseBuilder = require('./BaseBuilder')
4
2
  const { DRAFT_COLUMNS_MAP } = require('../../common/constants/draft')
5
3
 
@@ -108,6 +106,10 @@ class SelectBuilder extends BaseBuilder {
108
106
  this._forUpdate()
109
107
  }
110
108
 
109
+ if (this._obj.SELECT.forShareLock) {
110
+ this._forShareLock()
111
+ }
112
+
111
113
  this._parameters()
112
114
  this._outputObj.sql = /** @type {string} */ this._outputObj.sql.join(' ')
113
115
  return this._outputObj
@@ -133,6 +135,10 @@ class SelectBuilder extends BaseBuilder {
133
135
  }
134
136
  }
135
137
 
138
+ _forShareLock() {
139
+ this._outputObj.sql.push('FOR SHARE LOCK')
140
+ }
141
+
136
142
  _distinct() {
137
143
  this._outputObj.sql.push('DISTINCT')
138
144
  }
@@ -268,7 +274,7 @@ class SelectBuilder extends BaseBuilder {
268
274
  }
269
275
 
270
276
  // this function is overridden in hana in CustomSelectBuilder
271
- _buildRefElement(col, res, noQuoting) {
277
+ _buildRefElement(col, res) {
272
278
  res = new this.ReferenceBuilder(col, this._options, this._csn).build()
273
279
  return res
274
280
  }
@@ -281,7 +287,7 @@ class SelectBuilder extends BaseBuilder {
281
287
  ) {
282
288
  // REVISIT: db cleanup
283
289
  // slugify is needed for a unit test. Really required in production?
284
- const slugifiedAlias = col.as.replace(/\./g, '_')
290
+ const slugifiedAlias = col.as.includes('@odata.') ? col.as : col.as.replace(/\./g, '_')
285
291
  return ` AS ${this._quote(slugifiedAlias)}`
286
292
  }
287
293
 
@@ -439,13 +445,8 @@ class SelectBuilder extends BaseBuilder {
439
445
  }
440
446
 
441
447
  _val(obj) {
442
- let _val = obj.val
448
+ const _val = obj.val
443
449
  if (typeof _val === 'number' || _val === null) return { sql: _val, values: [] }
444
- // REVISIT: remove with cds^6
445
- if (typeof _val === 'string' && cds.env.features.extract_vals !== false) {
446
- const match = _val.match(/^'(.*)'$/)
447
- if (match) _val = match[1]
448
- }
449
450
  return { sql: '?', values: [_val] }
450
451
  }
451
452
 
@@ -119,7 +119,7 @@ class UpdateBuilder extends BaseBuilder {
119
119
  })
120
120
  }
121
121
 
122
- resMap.forEach((value, key, map) => {
122
+ resMap.forEach((value, key) => {
123
123
  if (value && value.sql) {
124
124
  sql.push(`${this._quoteElement(key)} = ${value.sql}`)
125
125
  this._outputObj.values.push(...value.values)
@@ -192,7 +192,7 @@ class UpdateBuilder extends BaseBuilder {
192
192
  }
193
193
  }
194
194
 
195
- _where(entityName) {
195
+ _where() {
196
196
  const where = new this.ExpressionBuilder(this._obj.UPDATE.where, this._options, this._csn).build()
197
197
  this._outputObj.sql.push('WHERE', where.sql)
198
198
  this._outputObj.values = this._outputObj.values.concat(where.values)
@@ -1,6 +1,5 @@
1
1
  const getColumns = require('../utils/columns')
2
- // REVISIT: Remove support for @odata.on... with @sap/cds ^6
3
- const ANNOTATIONS = ['@cds.on.insert', '@odata.on.insert', '@cds.on.update', '@odata.on.update']
2
+ const ANNOTATIONS = ['@cds.on.insert', '@cds.on.update']
4
3
  const { ensureNoDraftsSuffix } = require('../../common/utils/draft')
5
4
 
6
5
  const _getAnnotationNames = column => {
@@ -0,0 +1,5 @@
1
+ module.exports = {
2
+ BEGIN: '\x1b[1m\x1b[33mBEGIN\x1b[0m',
3
+ COMMIT: '\x1b[1m\x1b[32mCOMMIT\x1b[0m',
4
+ ROLLBACK: '\x1b[1m\x1b[91mROLLBACK\x1b[0m'
5
+ }
@@ -23,7 +23,7 @@ const getColumns = (entity, { _4db, onlyKeys } = { _4db: true, onlyKeys: false }
23
23
  if (element.isAssociation) continue
24
24
  if (_4db && entity._isDraftEnabled && elementName in DRAFT_COLUMNS_MAP) continue
25
25
  if ((cds.env.effective.odata.structs || cds.env.features.ucsn_struct_conversion) && element.elements) {
26
- columnNames.push(...resolveStructured({ structName: elementName, structProperties: [] }, element.elements, false))
26
+ columnNames.push(...resolveStructured({ element, structProperties: [] }, false))
27
27
  continue
28
28
  }
29
29
  columnNames.push(elementName)
@@ -62,6 +62,14 @@ const _propagateToParent = ({ parentElement, childElement, deep }, childRow, row
62
62
  }
63
63
 
64
64
  module.exports = (tKey, row, foreignKeyPropagations, isCompositionEffective) => {
65
+ if (row[tKey] === null) {
66
+ for (const foreignKeyPropagation of foreignKeyPropagations) {
67
+ if (!foreignKeyPropagation.fillChild) row[foreignKeyPropagation.parentElement.name] = null
68
+ }
69
+ if (!isCompositionEffective) delete row[tKey]
70
+ return
71
+ }
72
+
65
73
  const childRows = Array.isArray(row[tKey]) ? row[tKey] : [row[tKey]]
66
74
 
67
75
  for (const childRow of childRows) {
@@ -74,12 +82,12 @@ module.exports = (tKey, row, foreignKeyPropagations, isCompositionEffective) =>
74
82
  if (pk && !(pk in row)) _propagateToParent(foreignKeyPropagation, childRow, row)
75
83
  if (!(pk in row)) _generateParentField(foreignKeyPropagation, row)
76
84
 
77
- if (!isCompositionEffective) delete row[tKey]
78
- else _propagateToChid(foreignKeyPropagation, row, childRow)
85
+ if (isCompositionEffective) _propagateToChid(foreignKeyPropagation, row, childRow)
79
86
  } else {
80
87
  _generateChildField(foreignKeyPropagation, childRow)
81
88
  _propagateToParent(foreignKeyPropagation, childRow, row)
82
89
  }
83
90
  }
84
91
  }
92
+ if (!isCompositionEffective) delete row[tKey]
85
93
  }
@@ -0,0 +1,69 @@
1
+ const cds = require('../cds')
2
+
3
+ const handleDefaults = require('./defaults')
4
+
5
+ const _calculateExtensions = async function (ID, tag, tenant) {
6
+ let active, inactive
7
+ await cds.tx({ tenant }, async tx => {
8
+ if (tag || ID) {
9
+ const inactiveCqn = SELECT.from('cds.xt.Extensions').where({ activated: 'propertyBag' })
10
+ if (ID) {
11
+ inactiveCqn.where('ID !=', ID)
12
+ } else {
13
+ inactiveCqn.where('tag !=', tag)
14
+ }
15
+ inactive = await tx.run(inactiveCqn)
16
+ const activeCqn = SELECT.from('cds.xt.Extensions').where({ activated: 'database' })
17
+ if (ID) {
18
+ activeCqn.or({ ID })
19
+ } else {
20
+ if (tag) activeCqn.or({ tag })
21
+ }
22
+ active = await tx.run(activeCqn)
23
+ if (inactive.length) {
24
+ const deleteCqn = DELETE.from('cds.xt.Extensions').where(inactiveCqn.SELECT.where)
25
+ await tx.run(deleteCqn)
26
+ }
27
+ } else {
28
+ // activate all
29
+ inactive = []
30
+ active = await tx.run(SELECT.from('cds.xt.Extensions'))
31
+ }
32
+ })
33
+
34
+ return { active, inactive }
35
+ }
36
+
37
+ const _restoreExtensions = async function (tenant, active, inactive) {
38
+ await cds.tx({ tenant }, async tx => {
39
+ // delete all extensions
40
+ await tx.run(DELETE.from('cds.xt.Extensions'))
41
+ // active
42
+ active.forEach(row => {
43
+ row.csn = row.csn.replace(/,"@cds.extension":true/g, '')
44
+ row.activated = 'database'
45
+ row.timestamp = '$now'
46
+ })
47
+ await tx.run(INSERT.into('cds.xt.Extensions').entries(active))
48
+ // inactive
49
+ if (inactive.length) {
50
+ for (const na of inactive) {
51
+ for (const extension of JSON.parse(na.csn).extensions) {
52
+ await handleDefaults(extension, tx)
53
+ }
54
+ }
55
+ await tx.run(INSERT.into('cds.xt.Extensions').entries(inactive))
56
+ }
57
+ })
58
+ }
59
+
60
+ const activate = async function (ID, tag, tenant) {
61
+ const { active, inactive } = await _calculateExtensions(ID, tag, tenant)
62
+
63
+ const { 'cds.xt.DeploymentService': ds } = cds.services
64
+ await ds.extend(tenant)
65
+
66
+ await _restoreExtensions(tenant, active, inactive)
67
+ }
68
+
69
+ module.exports = activate
@@ -0,0 +1,41 @@
1
+ const cds = require('../cds')
2
+
3
+ const { validateExtension } = require('./validation')
4
+ const handleDefaults = require('./defaults')
5
+ const activateExt = require('./activate')
6
+
7
+ const _isCSN = str => str.substring(0, 1) === '{'
8
+
9
+ const add = async function (req) {
10
+ let { extension, tag, activate } = req.data
11
+ if (!extension || !extension.length) req.reject(400, 'Missing extension')
12
+ if (!activate) activate = 'database'
13
+ if (!tag) tag = null
14
+ const tenant = req.tenant || (req.user.is('internal-user') && req.data.tenant)
15
+
16
+ const csn = _isCSN(extension) ? JSON.parse(extension) : cds.parse.cdl(extension)
17
+ if (csn.requires) delete csn.requires
18
+ await validateExtension(csn, tenant, req)
19
+
20
+ const ID = cds.utils.uuid()
21
+ await cds.tx({ tenant }, async tx => {
22
+ await tx.run(INSERT.into('cds.xt.Extensions').entries([{ ID, tag, csn: JSON.stringify(csn), activated: activate }]))
23
+ if (activate === 'propertyBag' && csn.extensions) csn.extensions.forEach(async ext => await handleDefaults(ext, tx))
24
+ })
25
+
26
+ if (activate === 'database') {
27
+ await activateExt(ID, tag, tenant)
28
+ }
29
+ }
30
+
31
+ const promote = async function (req) {
32
+ let { tag, activate } = req.data
33
+ if (!activate) activate = 'database'
34
+ if (!tag) tag = null
35
+ const tenant = req.tenant || (req.user.is('internal-user') && req.data.tenant) || ''
36
+ if (activate !== 'database') req.reject(400, 'Promote to propertyBag is not supported')
37
+
38
+ await activateExt(null, tag, tenant)
39
+ }
40
+
41
+ module.exports = { add, promote }
@@ -0,0 +1,68 @@
1
+ const cds = require('../cds')
2
+
3
+ const { validateCsn, validateExtensionFields, validateExtension } = require('./validation')
4
+ const handleDefaults = require('./defaults')
5
+ const resolveViews = require('./views')
6
+
7
+ const _getCsn = req => {
8
+ const csn = {
9
+ extensions: req.data.extensions.map(ext => JSON.parse(ext))
10
+ }
11
+
12
+ return csn
13
+ }
14
+
15
+ const _addAnnotation = extension => {
16
+ Object.values(extension.elements).forEach(el => {
17
+ el['@cds.extension'] = true
18
+ })
19
+ }
20
+
21
+ const _addViews = csn => {
22
+ csn.extensions.forEach(extension => {
23
+ const target = cds.model.definitions[extension.extend]
24
+ const views_ = []
25
+ const view = resolveViews(target, views_)
26
+ extension.extend = view && view.name
27
+ _addAnnotation(extension)
28
+
29
+ // All projection views leading to the db entity are extended with back pack in case view columns are explicitly listed.
30
+ // The views using projections with '*' obtain the back pack automatically.
31
+ views_.forEach(view => {
32
+ if (!view.projection || (view.projection.columns && !view.projection.columns.some(col => col === '*'))) {
33
+ csn.extensions.push({
34
+ extend: view.name,
35
+ columns: Object.keys(extension.elements).map(key => {
36
+ return { ref: [key] }
37
+ })
38
+ })
39
+ }
40
+ })
41
+ })
42
+ }
43
+
44
+ const _addExtension = async function (csn, req) {
45
+ const tx = cds.tx(req)
46
+ await tx.run(
47
+ INSERT.into('cds.xt.Extensions').entries([
48
+ { ID: cds.utils.uuid(), tag: 'uiflex', csn: JSON.stringify(csn), activated: 'propertyBag' }
49
+ ])
50
+ )
51
+
52
+ // defaults
53
+ for (const ext of req.data.extensions) {
54
+ const extension = JSON.parse(ext)
55
+ await handleDefaults(extension, tx, false)
56
+ }
57
+ }
58
+
59
+ const addExtension = async function (req) {
60
+ const csn = _getCsn(req)
61
+ validateCsn(csn, req)
62
+ validateExtensionFields(csn, req)
63
+ _addViews(csn, cds)
64
+ await validateExtension(csn, req.tenant, req)
65
+ await _addExtension(csn, req)
66
+ }
67
+
68
+ module.exports = addExtension
@@ -0,0 +1,39 @@
1
+ const cds = require('../cds')
2
+
3
+ const { ensureDraftsSuffix } = require('../common/utils/draft')
4
+ const resolveViews = require('./views')
5
+ const { EXT_BACK_PACK } = require('./utils')
6
+
7
+ const _needsQuotations = t => t instanceof cds.builtin.classes.string || t instanceof cds.builtin.classes.date
8
+
9
+ const _getDraftTable = view => {
10
+ return cds.model.definitions[view]._isDraftEnabled ? ensureDraftsSuffix(view) : undefined
11
+ }
12
+
13
+ const handleDefaults = async (extension, tx, checkDb = true) => {
14
+ const target = cds.model.definitions[extension.extend]
15
+ const dbEntity = resolveViews(target).name
16
+
17
+ if (checkDb && target.name !== dbEntity) return // only db entities
18
+
19
+ const draft = _getDraftTable(extension.extend)
20
+ const ext = Object.keys(extension.elements)
21
+ .filter(key => extension.elements[key].default)
22
+ .map(key => {
23
+ const element = extension.elements[key]
24
+ // .type as ui flex extensions are not linked
25
+ const t = cds.model.definitions[element.type] || cds.builtin.types[element.type]
26
+ const value = t && _needsQuotations(t) ? `"${element.default.val}"` : element.default.val
27
+ return `"${key}":${value}`
28
+ })
29
+
30
+ if (ext.length !== 0) {
31
+ const extStr = ext.join(',')
32
+ const changed = `'{${extStr},' || substr(${EXT_BACK_PACK}, 2, length(${EXT_BACK_PACK})-1)`
33
+ const assign = `${EXT_BACK_PACK} = CASE WHEN ${EXT_BACK_PACK} IS NULL THEN '{${extStr}}' ELSE ${changed} END`
34
+ await tx.run(UPDATE(dbEntity).with(assign))
35
+ if (draft) await tx.run(UPDATE(draft).with(assign))
36
+ }
37
+ }
38
+
39
+ module.exports = handleDefaults
@@ -1,7 +1,7 @@
1
1
  const { EXT_BACK_PACK, hasExtendedEntity, getTargetRead } = require('../utils')
2
2
 
3
- const getTemplate = require('../../../common/utils/template')
4
- const templateProcessor = require('../../../common/utils/templateProcessor')
3
+ const getTemplate = require('../../common/utils/template')
4
+ const templateProcessor = require('../../common/utils/templateProcessor')
5
5
 
6
6
  const _pick = element => {
7
7
  return element['@cds.extension']
@@ -1,7 +1,7 @@
1
1
  const { EXT_BACK_PACK, getTargetWrite, isExtendedEntity } = require('../utils')
2
2
 
3
- const getTemplate = require('../../../common/utils/template')
4
- const templateProcessor = require('../../../common/utils/templateProcessor')
3
+ const getTemplate = require('../../common/utils/template')
4
+ const templateProcessor = require('../../common/utils/templateProcessor')
5
5
 
6
6
  const _pick = element => {
7
7
  return element['@cds.extension']
@@ -0,0 +1,61 @@
1
+ const fs = require('fs')
2
+ const path = require('path')
3
+ const cds = require('../cds')
4
+
5
+ const activate = require('./activate')
6
+ const { validateExtension } = require('./validation')
7
+ const { collectFiles, getCompilerError, exists } = require('./utils')
8
+ const { packTarArchive, unpackTarArchive } = require('../../../lib/utils/resources')
9
+
10
+ const TEMP_DIR = fs.realpathSync(require('os').tmpdir())
11
+
12
+ const _compileProject = async function (extension, req) {
13
+ let csn, root
14
+ try {
15
+ root = await fs.promises.mkdtemp(`${TEMP_DIR}${path.sep}extension-`)
16
+ await unpackTarArchive(extension, root)
17
+ csn = await cds.compile(collectFiles(root, ['.cds', '.json']), { flavor: 'parsed' })
18
+ if (csn.requires) delete csn.requires
19
+ } catch (err) {
20
+ if (err.messages) req.reject(400, getCompilerError(err.messages))
21
+ else throw err
22
+ } finally {
23
+ if (await exists(root)) {
24
+ await (fs.promises.rm || fs.promises.rmdir)(root, { recursive: true, force: true })
25
+ }
26
+ }
27
+
28
+ return csn
29
+ }
30
+
31
+ const base = async function (req) {
32
+ const cdsFiles = cds.resolve('*').filter(f => f.startsWith(cds.root) && !f.includes('node_modules'))
33
+ const csvObj = await cds.deploy.resources()
34
+ const csvFiles = Object.keys(csvObj).filter(f => f.startsWith(cds.root) && !f.includes('node_modules'))
35
+ const i18nFiles = collectFiles(cds.root, ['.properties'])
36
+ if (req._.res) req._.res.set('content-type', 'application/octet-stream; charset=binary')
37
+
38
+ return packTarArchive([...cdsFiles, ...csvFiles, ...i18nFiles], cds.root)
39
+ }
40
+
41
+ const push = async function (req) {
42
+ let { extension } = req.data
43
+ if (!extension || !extension.data) req.reject(400, 'Missing extension')
44
+ const csn = await _compileProject(extension.data, req)
45
+ if (!csn) req.reject(400, 'Missing or bad extension')
46
+ const tenant = req.tenant
47
+ await validateExtension(csn, tenant, req)
48
+
49
+ const ID = cds.utils.uuid()
50
+ await cds.tx({ tenant }, async tx => {
51
+ await tx.run(
52
+ INSERT.into('cds.xt.Extensions').entries([
53
+ { ID, csn: JSON.stringify(csn), sources: extension.data, activated: 'database' }
54
+ ])
55
+ )
56
+ })
57
+
58
+ await activate(ID, null, tenant)
59
+ }
60
+
61
+ module.exports = { base, push }
@@ -0,0 +1,21 @@
1
+ const cds = require('../cds')
2
+
3
+ const addExtension = require('./addExtension')
4
+ const { add, promote } = require('./add')
5
+ const { base, push } = require('./push')
6
+ const { transformExtendedFieldsCREATE, transformExtendedFieldsUPDATE } = require('./handler/transformWRITE')
7
+ const { transformExtendedFieldsREAD } = require('./handler/transformREAD')
8
+ const { transformExtendedFieldsRESULT } = require('./handler/transformRESULT')
9
+
10
+ module.exports = async function () {
11
+ this.on('addExtension', addExtension)
12
+ this.on('add', add)
13
+ this.on('promote', promote)
14
+ this.on('base', base)
15
+ this.on('push', push)
16
+ cds.db
17
+ .before('CREATE', transformExtendedFieldsCREATE)
18
+ .before('UPDATE', transformExtendedFieldsUPDATE)
19
+ .before('READ', transformExtendedFieldsREAD)
20
+ .after('READ', transformExtendedFieldsRESULT)
21
+ }
@@ -1,5 +1,8 @@
1
- const { ensureNoDraftsSuffix } = require('../../common/utils/draft')
2
- const { ensureUnlocalized } = require('../../fiori/utils/handler')
1
+ const fs = require('fs')
2
+ const path = require('path')
3
+
4
+ const { ensureNoDraftsSuffix } = require('../common/utils/draft')
5
+ const { ensureUnlocalized } = require('../fiori/utils/handler')
3
6
 
4
7
  const EXT_BACK_PACK = 'extensions__'
5
8
 
@@ -83,11 +86,44 @@ const getExtendedFields = (entityName, model) => {
83
86
  })
84
87
  }
85
88
 
89
+ const getCompilerError = messages => {
90
+ const defaultMsg = 'Error while compiling extension'
91
+ if (!messages) return defaultMsg
92
+
93
+ for (const msg of messages) {
94
+ if (msg.severity === 'Error') return msg.message
95
+ }
96
+
97
+ return defaultMsg
98
+ }
99
+
100
+ const collectFiles = (dir, extensions) => {
101
+ const files = []
102
+ fs.readdirSync(dir).forEach(file => {
103
+ const abs = path.join(dir, file)
104
+ if (fs.statSync(abs).isDirectory() && !abs.includes('node_modules')) files.push(...collectFiles(abs, extensions))
105
+ else if (!extensions || extensions.includes(path.extname(abs))) files.push(abs)
106
+ })
107
+
108
+ return files
109
+ }
110
+
111
+ const exists = async fileOrDir => {
112
+ try {
113
+ return await fs.promises.stat(fileOrDir)
114
+ } catch (_) {
115
+ return false
116
+ }
117
+ }
118
+
86
119
  module.exports = {
87
120
  EXT_BACK_PACK,
88
121
  getTargetRead,
89
122
  getTargetWrite,
90
123
  isExtendedEntity,
91
124
  hasExtendedEntity,
92
- getExtendedFields
125
+ getExtendedFields,
126
+ getCompilerError,
127
+ collectFiles,
128
+ exists
93
129
  }
@@ -0,0 +1,53 @@
1
+ const cds = require('../cds')
2
+
3
+ const { getCompilerError } = require('./utils')
4
+
5
+ const validateCsn = (csn, req) => {
6
+ if (!csn) req.reject(400, 'Missing extension')
7
+ if (!csn.extensions) return
8
+
9
+ csn.extensions.forEach(extension => {
10
+ if (!extension.extend || !cds.model.definitions[extension.extend]) {
11
+ req.reject(400, 'Invalid extension. Parameter "extend" missing or malformed')
12
+ }
13
+
14
+ if (!extension.elements) {
15
+ req.reject(400, 'Invalid extension. Missing parameter "elements"')
16
+ }
17
+ })
18
+ }
19
+
20
+ const validateExtensionFields = (csn, req) => {
21
+ if (!csn.extensions) return
22
+
23
+ csn.extensions.forEach(extension => {
24
+ if (extension.elements) {
25
+ Object.keys(extension.elements).forEach(name => {
26
+ if (!/^[A-Za-z]\w*$/.test(name)) {
27
+ req.reject(400, `Invalid extension. Bad element name "${name}"`)
28
+ }
29
+
30
+ if (Object.keys(cds.model.definitions[extension.extend].elements).includes(name)) {
31
+ req.reject(400, `Invalid extension. Element "${name}" already exists`)
32
+ }
33
+ })
34
+ }
35
+ })
36
+ }
37
+
38
+ const validateExtension = async (ext, tenant, req) => {
39
+ try {
40
+ const { 'cds.xt.ModelProviderService': mps } = cds.services
41
+ const csn = await mps.getCsn(tenant, ['*'])
42
+ const extCsn = cds.compile.to.json(ext)
43
+ await cds.compile.to.csn({ 'base.csn': JSON.stringify(csn), 'ext.csn': extCsn })
44
+ } catch (err) {
45
+ req.reject(400, getCompilerError(err.messages))
46
+ }
47
+ }
48
+
49
+ module.exports = {
50
+ validateCsn,
51
+ validateExtensionFields,
52
+ validateExtension
53
+ }
@@ -0,0 +1,12 @@
1
+ const _isProjection = target => target && target.query && target.query._target
2
+
3
+ const resolveViews = (target, views_ = []) => {
4
+ if (_isProjection(target)) {
5
+ views_.push(target)
6
+ return resolveViews(target.query._target, views_)
7
+ }
8
+
9
+ return target
10
+ }
11
+
12
+ module.exports = resolveViews
@@ -11,6 +11,7 @@ const {
11
11
  const { readAndDeleteKeywords, isActiveEntityRequested, getKeyData } = require('../utils/where')
12
12
  const { isDraftRootEntity } = require('../../fiori/utils/csn')
13
13
  const { getColumns } = require('../../cds-services/services/utils/columns')
14
+ const { setStatusCodeAndHeader, getKeyProperty } = require('../utils/handler')
14
15
 
15
16
  const { DRAFT_COLUMNS_MAP } = require('../../common/constants/draft')
16
17
 
@@ -174,11 +175,12 @@ const _handler = async function (req) {
174
175
  })
175
176
  ])
176
177
 
178
+ const k = getKeyProperty(req.target.keys)
179
+ setStatusCodeAndHeader(req._.odataRes, { [k]: result[k] }, req.target.name.replace(`${this.name}.`, ''), true)
180
+
177
181
  return result
178
182
  }
179
183
 
180
- module.exports = cds.service.impl(function () {
181
- for (const entity of Object.values(this.entities).filter(e => e._isDraftEnabled)) {
182
- this.on('draftActivate', entity, _handler)
183
- }
184
+ module.exports = cds.service.impl(function (srv, entity) {
185
+ srv.on('draftActivate', entity, _handler)
184
186
  })