@sap/cds 5.9.6 → 6.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (381) hide show
  1. package/CHANGELOG.md +266 -20
  2. package/apis/services.d.ts +1 -1
  3. package/app/fiori/preview.js +2 -6
  4. package/app/index.js +3 -3
  5. package/bin/build/buildTaskEngine.js +17 -15
  6. package/bin/build/buildTaskFactory.js +29 -19
  7. package/bin/build/buildTaskHandler.js +27 -11
  8. package/bin/build/buildTaskProvider.js +2 -4
  9. package/bin/build/buildTaskProviderFactory.js +11 -16
  10. package/bin/build/constants.js +14 -6
  11. package/bin/build/csv-reader.js +2 -1
  12. package/bin/build/index.js +12 -18
  13. package/bin/build/provider/buildTaskHandlerEdmx.js +3 -39
  14. package/bin/build/provider/buildTaskHandlerFeatureToggles.js +149 -0
  15. package/bin/build/provider/buildTaskHandlerInternal.js +2 -3
  16. package/bin/build/provider/buildTaskProviderInternal.js +108 -239
  17. package/bin/build/provider/fiori/index.js +2 -2
  18. package/bin/build/provider/hana/2migration.js +11 -11
  19. package/bin/build/provider/hana/2tabledata.js +3 -3
  20. package/bin/build/provider/hana/index.js +89 -99
  21. package/bin/build/provider/hana/migrationtable.js +4 -3
  22. package/bin/build/provider/java/index.js +101 -0
  23. package/bin/build/provider/java-cf/index.js +1 -101
  24. package/bin/build/provider/mtx/index.js +90 -53
  25. package/bin/build/provider/mtx/resourcesTarBuilder.js +68 -0
  26. package/bin/build/provider/mtx-sidecar/index.js +80 -0
  27. package/bin/build/provider/node-cf/index.js +1 -308
  28. package/bin/build/provider/nodejs/index.js +189 -0
  29. package/bin/build/util.js +19 -31
  30. package/bin/cds.js +5 -3
  31. package/bin/deploy/to-hana/cfUtil.js +31 -6
  32. package/bin/deploy/to-hana/gitUtil.js +5 -3
  33. package/bin/deploy/to-hana/hana.js +9 -10
  34. package/bin/{build → deploy/to-hana}/mtaUtil.js +10 -9
  35. package/bin/mtx/in-cds.js +19 -7
  36. package/bin/serve.js +56 -21
  37. package/bin/utils/log.js +13 -30
  38. package/bin/version.js +5 -4
  39. package/common.cds +61 -16
  40. package/lib/compile/cdsc.js +3 -2
  41. package/lib/compile/etc/_localized.js +15 -14
  42. package/lib/compile/for/drafts.js +3 -4
  43. package/lib/compile/for/java.js +13 -10
  44. package/lib/compile/for/nodejs.js +8 -8
  45. package/lib/compile/for/odata.js +7 -12
  46. package/lib/compile/for/sql.js +5 -6
  47. package/lib/compile/index.js +5 -4
  48. package/lib/compile/load.js +9 -11
  49. package/lib/compile/minify.js +8 -5
  50. package/lib/compile/parse.js +4 -2
  51. package/lib/compile/resolve.js +18 -15
  52. package/lib/compile/to/edm.js +0 -1
  53. package/lib/compile/to/gql.js +3 -2
  54. package/lib/compile/to/json.js +24 -17
  55. package/lib/connect/bindings.js +3 -2
  56. package/lib/connect/index.js +5 -5
  57. package/lib/core/classes.js +74 -2
  58. package/lib/core/entities.js +52 -3
  59. package/lib/core/reflect.js +2 -1
  60. package/lib/deploy.js +11 -8
  61. package/lib/env/defaults.js +4 -3
  62. package/lib/env/index.js +71 -31
  63. package/lib/env/presets.js +1 -14
  64. package/lib/env/requires.js +70 -20
  65. package/lib/env/serviceBindings.js +147 -0
  66. package/lib/i18n/localize.js +22 -23
  67. package/lib/index.js +148 -144
  68. package/lib/log/errors.js +55 -12
  69. package/lib/log/format/kibana.js +1 -1
  70. package/lib/log/index.js +4 -0
  71. package/lib/ql/SELECT.js +7 -2
  72. package/lib/ql/Whereable.js +8 -2
  73. package/lib/ql/index.js +2 -2
  74. package/lib/req/assert.js +71 -0
  75. package/lib/req/cds-context.js +38 -70
  76. package/lib/req/context.js +34 -21
  77. package/lib/req/request.js +12 -18
  78. package/lib/req/response.js +6 -2
  79. package/lib/req/user.js +30 -22
  80. package/lib/serve/Service-api.js +17 -12
  81. package/lib/serve/Service-dispatch.js +5 -9
  82. package/lib/serve/Service-methods.js +4 -3
  83. package/lib/serve/Transaction.js +24 -21
  84. package/lib/serve/adapters.js +15 -5
  85. package/lib/serve/factory.js +23 -20
  86. package/lib/serve/index.js +51 -54
  87. package/lib/utils/axios.js +8 -12
  88. package/lib/utils/index.js +3 -3
  89. package/lib/utils/resources/index.js +1 -44
  90. package/lib/utils/resources/tar.js +2 -1
  91. package/lib/utils/tests.js +13 -15
  92. package/libx/_runtime/.eslintrc +1 -1
  93. package/libx/_runtime/audit/Service.js +6 -4
  94. package/libx/_runtime/audit/generic/personal/access.js +19 -43
  95. package/libx/_runtime/audit/generic/personal/index.js +40 -34
  96. package/libx/_runtime/audit/generic/personal/modification.js +11 -9
  97. package/libx/_runtime/audit/generic/personal/utils.js +13 -6
  98. package/libx/_runtime/audit/utils/v2.js +6 -3
  99. package/libx/_runtime/auth/index.js +71 -66
  100. package/libx/_runtime/auth/strategies/JWT.js +3 -2
  101. package/libx/_runtime/auth/strategies/mock.js +54 -53
  102. package/libx/_runtime/auth/strategies/xssecUtils.js +3 -4
  103. package/libx/_runtime/auth/strategies/xsuaa.js +3 -2
  104. package/libx/_runtime/auth/utils.js +2 -15
  105. package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +128 -42
  106. package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +6 -3
  107. package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +93 -73
  108. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +10 -45
  109. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +5 -9
  110. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +9 -5
  111. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +4 -2
  112. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +60 -53
  113. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +1 -1
  114. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +15 -21
  115. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +8 -15
  116. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/expandToCQN.js +29 -41
  117. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/index.js +1 -4
  118. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/readToCQN.js +13 -13
  119. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/selectToCQN.js +0 -7
  120. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/utils.js +24 -1
  121. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/edm/EdmEntityContainer.js +1 -1
  122. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/UriHelper.js +4 -3
  123. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/utils/PrimitiveValueDecoder.js +4 -5
  124. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/utils/ValueConverter.js +4 -3
  125. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/validator/ValueValidator.js +5 -3
  126. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/core/ResponseHeaderSetter.js +2 -0
  127. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/DebugSerializingCommand.js +1 -1
  128. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/PresetResponseHeadersCommand.js +1 -1
  129. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/SerializingCommand.js +1 -1
  130. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/SetResponseHeadersCommand.js +1 -1
  131. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/ContextURLFactory.js +3 -2
  132. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/ErrorJsonSerializer.js +3 -1
  133. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/SerializerFactory.js +1 -0
  134. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/TrustedResourceJsonSerializer.js +3 -3
  135. package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +36 -25
  136. package/libx/_runtime/cds-services/adapter/odata-v4/utils/handlerUtils.js +100 -91
  137. package/libx/_runtime/cds-services/adapter/odata-v4/utils/metaInfo.js +382 -0
  138. package/libx/_runtime/cds-services/adapter/odata-v4/utils/oDataConfiguration.js +1 -4
  139. package/libx/_runtime/cds-services/adapter/odata-v4/utils/omitValues.js +5 -6
  140. package/libx/_runtime/cds-services/adapter/odata-v4/utils/readAfterWrite.js +77 -21
  141. package/libx/_runtime/cds-services/adapter/odata-v4/utils/request.js +3 -11
  142. package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +91 -69
  143. package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +27 -6
  144. package/libx/_runtime/cds-services/adapter/rest/utils/validation-checks.js +7 -17
  145. package/libx/_runtime/cds-services/services/Service.js +17 -76
  146. package/libx/_runtime/cds-services/services/utils/columns.js +6 -4
  147. package/libx/_runtime/cds-services/services/utils/compareJson.js +1 -53
  148. package/libx/_runtime/cds-services/services/utils/differ.js +15 -19
  149. package/libx/_runtime/cds-services/util/assert.js +107 -34
  150. package/libx/_runtime/cds.js +1 -31
  151. package/libx/_runtime/common/aspects/Association.js +40 -54
  152. package/libx/_runtime/common/aspects/any.js +61 -6
  153. package/libx/_runtime/common/aspects/entity.js +19 -79
  154. package/libx/_runtime/common/composition/data.js +2 -2
  155. package/libx/_runtime/common/composition/delete.js +16 -18
  156. package/libx/_runtime/common/composition/tree.js +10 -10
  157. package/libx/_runtime/common/composition/update.js +3 -2
  158. package/libx/_runtime/common/constants/events.js +15 -0
  159. package/libx/_runtime/common/error/entry.js +9 -3
  160. package/libx/_runtime/common/error/frontend.js +13 -19
  161. package/libx/_runtime/common/error/index.js +8 -3
  162. package/libx/_runtime/common/generic/auth/capabilities.js +2 -1
  163. package/libx/_runtime/common/generic/auth/constants.js +1 -4
  164. package/libx/_runtime/common/generic/auth/requires.js +1 -1
  165. package/libx/_runtime/common/generic/auth/restrict.js +12 -28
  166. package/libx/_runtime/common/generic/auth/restrictions.js +12 -4
  167. package/libx/_runtime/common/generic/auth/utils.js +2 -1
  168. package/libx/_runtime/common/generic/crud.js +9 -60
  169. package/libx/_runtime/common/generic/etag.js +41 -7
  170. package/libx/_runtime/common/generic/input.js +128 -66
  171. package/libx/_runtime/common/generic/paging.js +9 -3
  172. package/libx/_runtime/common/generic/put.js +2 -2
  173. package/libx/_runtime/common/generic/sorting.js +11 -4
  174. package/libx/_runtime/common/generic/temporal.js +0 -5
  175. package/libx/_runtime/common/i18n/messages.properties +2 -1
  176. package/libx/_runtime/common/utils/binary.js +69 -0
  177. package/libx/_runtime/common/utils/cqn.js +39 -14
  178. package/libx/_runtime/common/utils/cqn2cqn4sql.js +93 -59
  179. package/libx/_runtime/common/utils/csn.js +87 -85
  180. package/libx/_runtime/common/utils/dollar.js +8 -7
  181. package/libx/_runtime/common/utils/draft.js +1 -1
  182. package/libx/_runtime/common/utils/foreignKeyPropagations.js +23 -7
  183. package/libx/_runtime/common/utils/generateOnCond.js +2 -1
  184. package/libx/_runtime/common/utils/keys.js +30 -13
  185. package/libx/_runtime/common/utils/postProcessing.js +6 -1
  186. package/libx/_runtime/common/utils/quotingStyles.js +0 -23
  187. package/libx/_runtime/common/utils/resolveStructured.js +23 -26
  188. package/libx/_runtime/common/utils/resolveView.js +4 -1
  189. package/libx/_runtime/common/utils/rewriteAsterisks.js +3 -0
  190. package/libx/_runtime/common/utils/search2cqn4sql.js +4 -13
  191. package/libx/_runtime/common/utils/searchToLike.js +9 -13
  192. package/libx/_runtime/common/utils/streamProp.js +35 -0
  193. package/libx/_runtime/common/utils/structured.js +12 -18
  194. package/libx/_runtime/common/utils/template.js +3 -5
  195. package/libx/_runtime/common/utils/templateProcessor.js +22 -14
  196. package/libx/_runtime/common/utils/unionCqnTemplate.js +4 -14
  197. package/libx/_runtime/db/Service.js +2 -1
  198. package/libx/_runtime/db/expand/expand-v2.js +2 -2
  199. package/libx/_runtime/db/expand/expandCQNToJoin.js +7 -6
  200. package/libx/_runtime/db/generic/input.js +14 -17
  201. package/libx/_runtime/db/generic/integrity.js +1 -2
  202. package/libx/_runtime/db/generic/update.js +14 -1
  203. package/libx/_runtime/db/query/read.js +0 -1
  204. package/libx/_runtime/db/query/update.js +1 -1
  205. package/libx/_runtime/db/sql-builder/BaseBuilder.js +1 -1
  206. package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +5 -31
  207. package/libx/_runtime/db/sql-builder/InsertBuilder.js +1 -1
  208. package/libx/_runtime/db/sql-builder/ReferenceBuilder.js +0 -9
  209. package/libx/_runtime/db/sql-builder/SelectBuilder.js +11 -10
  210. package/libx/_runtime/db/sql-builder/UpdateBuilder.js +2 -2
  211. package/libx/_runtime/db/sql-builder/annotations.js +1 -2
  212. package/libx/_runtime/db/utils/coloredTxCommands.js +5 -0
  213. package/libx/_runtime/db/utils/columns.js +1 -1
  214. package/libx/_runtime/db/utils/propagateForeignKeys.js +10 -2
  215. package/libx/_runtime/extensibility/activate.js +69 -0
  216. package/libx/_runtime/extensibility/add.js +41 -0
  217. package/libx/_runtime/extensibility/addExtension.js +68 -0
  218. package/libx/_runtime/extensibility/defaults.js +39 -0
  219. package/libx/_runtime/extensibility/{uiflex/handler → handler}/transformREAD.js +0 -0
  220. package/libx/_runtime/extensibility/{uiflex/handler → handler}/transformRESULT.js +2 -2
  221. package/libx/_runtime/extensibility/{uiflex/handler → handler}/transformWRITE.js +2 -2
  222. package/libx/_runtime/extensibility/push.js +61 -0
  223. package/libx/_runtime/extensibility/service.js +21 -0
  224. package/libx/_runtime/extensibility/{uiflex/utils.js → utils.js} +39 -3
  225. package/libx/_runtime/extensibility/validation.js +53 -0
  226. package/libx/_runtime/extensibility/views.js +12 -0
  227. package/libx/_runtime/fiori/generic/activate.js +6 -4
  228. package/libx/_runtime/fiori/generic/before.js +17 -29
  229. package/libx/_runtime/fiori/generic/cancel.js +2 -4
  230. package/libx/_runtime/fiori/generic/delete.js +2 -4
  231. package/libx/_runtime/fiori/generic/edit.js +3 -7
  232. package/libx/_runtime/fiori/generic/index.js +31 -0
  233. package/libx/_runtime/fiori/generic/new.js +2 -4
  234. package/libx/_runtime/fiori/generic/patch.js +4 -8
  235. package/libx/_runtime/fiori/generic/prepare.js +2 -4
  236. package/libx/_runtime/fiori/generic/read.js +137 -162
  237. package/libx/_runtime/fiori/generic/readOverDraft.js +10 -4
  238. package/libx/_runtime/fiori/utils/handler.js +10 -5
  239. package/libx/_runtime/fiori/utils/where.js +1 -4
  240. package/libx/_runtime/hana/Service.js +14 -7
  241. package/libx/_runtime/hana/customBuilder/CustomSelectBuilder.js +1 -1
  242. package/libx/_runtime/hana/dynatrace.js +2 -2
  243. package/libx/_runtime/hana/localized.js +7 -6
  244. package/libx/_runtime/hana/pool.js +9 -6
  245. package/libx/_runtime/hana/search.js +2 -3
  246. package/libx/_runtime/hana/{searchToContains.js → search2Contains.js} +5 -2
  247. package/libx/_runtime/hana/search2cqn4sql.js +20 -17
  248. package/libx/_runtime/index.js +2 -6
  249. package/libx/_runtime/messaging/AMQPWebhookMessaging.js +11 -2
  250. package/libx/_runtime/messaging/common-utils/AMQPClient.js +4 -3
  251. package/libx/_runtime/messaging/common-utils/appId.js +9 -0
  252. package/libx/_runtime/messaging/common-utils/authorizedRequest.js +2 -18
  253. package/libx/_runtime/messaging/common-utils/connections.js +1 -1
  254. package/libx/_runtime/messaging/enterprise-messaging-shared.js +2 -2
  255. package/libx/_runtime/messaging/enterprise-messaging-utils/EMManagement.js +305 -231
  256. package/libx/_runtime/messaging/enterprise-messaging-utils/cloudEvents.js +2 -2
  257. package/libx/_runtime/messaging/enterprise-messaging-utils/options-management.js +15 -8
  258. package/libx/_runtime/messaging/enterprise-messaging-utils/options-messaging.js +57 -14
  259. package/libx/_runtime/messaging/enterprise-messaging.js +14 -19
  260. package/libx/_runtime/messaging/file-based.js +2 -1
  261. package/libx/_runtime/messaging/http-utils/token.js +18 -6
  262. package/libx/_runtime/messaging/message-queuing-utils/options-management.js +22 -12
  263. package/libx/_runtime/messaging/message-queuing-utils/options-messaging.js +27 -14
  264. package/libx/_runtime/messaging/message-queuing.js +138 -85
  265. package/libx/_runtime/messaging/outbox/utils.js +13 -7
  266. package/libx/_runtime/messaging/redis-messaging.js +0 -1
  267. package/libx/_runtime/messaging/service.js +4 -1
  268. package/libx/_runtime/remote/Service.js +24 -18
  269. package/libx/_runtime/remote/utils/client.js +84 -46
  270. package/libx/_runtime/remote/utils/data.js +23 -6
  271. package/libx/_runtime/sqlite/Service.js +14 -13
  272. package/libx/_runtime/sqlite/convertAssocToOneManaged.js +2 -0
  273. package/libx/_runtime/sqlite/customBuilder/CustomSelectBuilder.js +1 -0
  274. package/libx/_runtime/sqlite/execute.js +3 -9
  275. package/libx/_runtime/types/api.js +23 -11
  276. package/libx/common/utils/ucsn.js +15 -9
  277. package/libx/odata/afterburner.js +109 -29
  278. package/libx/odata/cqn2odata.js +48 -9
  279. package/libx/odata/grammar.pegjs +261 -157
  280. package/libx/odata/index.js +21 -9
  281. package/libx/odata/parseToCqn.js +8 -5
  282. package/libx/odata/parser.js +1 -1
  283. package/libx/odata/utils.js +13 -3
  284. package/libx/rest/RestAdapter.js +173 -113
  285. package/libx/rest/RestRequest.js +3 -2
  286. package/libx/rest/middleware/create.js +8 -6
  287. package/libx/rest/middleware/delete.js +6 -13
  288. package/libx/rest/middleware/error.js +1 -1
  289. package/libx/rest/middleware/input.js +6 -6
  290. package/libx/rest/middleware/operation.js +8 -3
  291. package/libx/rest/middleware/parse.js +3 -3
  292. package/libx/rest/middleware/payload.js +12 -0
  293. package/libx/rest/middleware/read.js +12 -2
  294. package/libx/rest/middleware/update.js +3 -3
  295. package/package.json +4 -6
  296. package/server.js +3 -44
  297. package/srv/extensibility-service.cds +56 -0
  298. package/srv/extensibility-service.js +1 -0
  299. package/srv/extensions.cds +8 -0
  300. package/srv/model-provider.cds +59 -0
  301. package/srv/model-provider.js +163 -0
  302. package/srv/mtx.cds +2 -0
  303. package/srv/mtx.js +22 -0
  304. package/srv/outbox.cds +2 -0
  305. package/tasks/enterprise-messaging-deploy.js +19 -12
  306. package/lib/serve/Service-compat.js +0 -36
  307. package/libx/_runtime/audit/generic/personal/constants.js +0 -4
  308. package/libx/_runtime/auth/strategies/dwc.js +0 -45
  309. package/libx/_runtime/cds-services/adapter/odata-v4/utils/dispatcherUtils.js +0 -56
  310. package/libx/_runtime/cds-services/adapter/rest/Rest.js +0 -183
  311. package/libx/_runtime/cds-services/adapter/rest/RestRequest.js +0 -67
  312. package/libx/_runtime/cds-services/adapter/rest/handlers/create.js +0 -82
  313. package/libx/_runtime/cds-services/adapter/rest/handlers/delete.js +0 -39
  314. package/libx/_runtime/cds-services/adapter/rest/handlers/operation.js +0 -63
  315. package/libx/_runtime/cds-services/adapter/rest/handlers/read.js +0 -52
  316. package/libx/_runtime/cds-services/adapter/rest/handlers/update.js +0 -81
  317. package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/index.js +0 -56
  318. package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/utils.js +0 -33
  319. package/libx/_runtime/cds-services/adapter/rest/to.js +0 -8
  320. package/libx/_runtime/cds-services/adapter/rest/utils/binary.js +0 -50
  321. package/libx/_runtime/cds-services/adapter/rest/utils/data.js +0 -117
  322. package/libx/_runtime/cds-services/adapter/rest/utils/header-checks.js +0 -14
  323. package/libx/_runtime/cds-services/adapter/rest/utils/key-value-utils.js +0 -30
  324. package/libx/_runtime/cds-services/adapter/rest/utils/parse-url.js +0 -250
  325. package/libx/_runtime/cds-services/adapter/rest/utils/result.js +0 -26
  326. package/libx/_runtime/cds-services/services/utils/handlerUtils.js +0 -200
  327. package/libx/_runtime/common/aspects/utils.js +0 -152
  328. package/libx/_runtime/common/toggles/handler.js +0 -21
  329. package/libx/_runtime/common/utils/extensibilityUtils.js +0 -18
  330. package/libx/_runtime/extensibility/mps/index.js +0 -5
  331. package/libx/_runtime/extensibility/mps/service.js +0 -111
  332. package/libx/_runtime/extensibility/mps/tar.js +0 -42
  333. package/libx/_runtime/extensibility/mps/utils.js +0 -11
  334. package/libx/_runtime/extensibility/uiflex/index.js +0 -54
  335. package/libx/_runtime/extensibility/uiflex/service.js +0 -276
  336. package/libx/_runtime/messaging/common-utils/naming-conventions.js +0 -20
  337. package/libx/_runtime/remote/utils/client-types.d.ts +0 -7
  338. package/libx/gql/GraphQLAdapter.js +0 -33
  339. package/libx/gql/constants/adapter.js +0 -69
  340. package/libx/gql/constants/cds.js +0 -18
  341. package/libx/gql/constants/graphql.js +0 -33
  342. package/libx/gql/readme.md +0 -1
  343. package/libx/gql/resolvers/crud/create.js +0 -20
  344. package/libx/gql/resolvers/crud/delete.js +0 -29
  345. package/libx/gql/resolvers/crud/index.js +0 -6
  346. package/libx/gql/resolvers/crud/read.js +0 -30
  347. package/libx/gql/resolvers/crud/update.js +0 -42
  348. package/libx/gql/resolvers/crud/utils/index.js +0 -36
  349. package/libx/gql/resolvers/field.js +0 -5
  350. package/libx/gql/resolvers/index.js +0 -7
  351. package/libx/gql/resolvers/mutation.js +0 -23
  352. package/libx/gql/resolvers/parse/ast/enrich.js +0 -52
  353. package/libx/gql/resolvers/parse/ast/fragment.js +0 -11
  354. package/libx/gql/resolvers/parse/ast/fromObject.js +0 -39
  355. package/libx/gql/resolvers/parse/ast/index.js +0 -3
  356. package/libx/gql/resolvers/parse/ast/meta.js +0 -4
  357. package/libx/gql/resolvers/parse/ast/variable.js +0 -7
  358. package/libx/gql/resolvers/parse/ast2cqn/columns.js +0 -44
  359. package/libx/gql/resolvers/parse/ast2cqn/entries.js +0 -31
  360. package/libx/gql/resolvers/parse/ast2cqn/index.js +0 -8
  361. package/libx/gql/resolvers/parse/ast2cqn/limit.js +0 -6
  362. package/libx/gql/resolvers/parse/ast2cqn/orderBy.js +0 -24
  363. package/libx/gql/resolvers/parse/ast2cqn/utils/index.js +0 -3
  364. package/libx/gql/resolvers/parse/ast2cqn/where.js +0 -70
  365. package/libx/gql/resolvers/parse/utils/index.js +0 -8
  366. package/libx/gql/resolvers/query.js +0 -13
  367. package/libx/gql/resolvers/root.js +0 -34
  368. package/libx/gql/schema/generate.js +0 -18
  369. package/libx/gql/schema/index.js +0 -5
  370. package/libx/gql/schema/mutation.js +0 -76
  371. package/libx/gql/schema/query.js +0 -108
  372. package/libx/gql/schema/typeDefMap.js +0 -45
  373. package/libx/gql/schema/utils/index.js +0 -54
  374. package/libx/gql/utils/index.js +0 -12
  375. package/libx/rest/middleware/auth.js +0 -20
  376. package/libx/rest/middleware/content.js +0 -19
  377. package/srv/flex.cds +0 -21
  378. package/srv/flex.js +0 -1
  379. package/srv/mps.cds +0 -23
  380. package/srv/mps.js +0 -1
  381. package/srv/outbox.js +0 -0
@@ -1,16 +1,19 @@
1
1
  const cds = require ('../../index')
2
- const _cached = Symbol('for Java')
3
2
 
4
3
  module.exports = function cds_compile_for_java (csn,o) {
5
- if (!csn) return
6
- const cached = csn[_cached]; if (cached) return cached
7
- // csn = cds.minify (csn)
8
- csn = cds.compile.for.drafts (csn,o)
9
- // Add a parsed _where clause for @restrict.{grant,where} annotations
10
- if (csn.definitions) for (let {'@restrict':rr} of Object.values(csn.definitions)) if (rr) {
11
- for (let r of rr) if (r.grant && r.where) try {
4
+ if ('_4java' in csn) return csn._4java
5
+ let dsn = csn // cds.minify (csn)
6
+ dsn = cds.compile.for.drafts (csn,o)
7
+ if (dsn.definitions) for (let [name,d] of Object.entries(dsn.definitions)) {
8
+ // Add @cds.external to external services
9
+ if (d.kind === 'service' && name in cds.requires) d['@cds.external'] = true
10
+ // Add parsed ._where clause to @restrict annotations
11
+ const rr = d['@restrict']
12
+ if (rr) for (let r of rr) if (r.grant && r.where) try {
12
13
  r._where = JSON.stringify (cds.parse.xpr(r.where))
13
14
  } catch(e){/* ignored */}
14
15
  }
15
- return csn[_cached] = csn
16
- }
16
+ Object.defineProperty (csn, '_4java', {value:dsn})
17
+ Object.defineProperty (dsn, '_4java', {value:dsn})
18
+ return dsn
19
+ }
@@ -1,12 +1,12 @@
1
1
  const cds = require ('../../index')
2
- const _cached = Symbol('for Node.js')
3
2
 
4
3
  module.exports = function cds_compile_for_nodejs (csn,o) {
5
- if (!csn) return
6
- const cached = csn[_cached]; if (cached) return cached
7
- // csn = cds.minify (csn)
8
- csn = cds.compile.for.drafts (csn,o) //> creates a partial copy -> avoid any cds.linked() before
9
- csn = cds.compile._localized.unfold_csn (csn)
10
- csn = cds.linked (csn)
11
- return csn[_cached] = csn
4
+ if ('_4nodejs' in csn) return csn._4nodejs
5
+ let dsn = csn // cds.minify (csn)
6
+ dsn = cds.compile.for.drafts (csn,o) //> creates a partial copy -> avoid any cds.linked() before
7
+ dsn = cds.compile._localized.unfold_csn (dsn)
8
+ dsn = cds.linked (dsn)
9
+ Object.defineProperty (csn, '_4nodejs', {value:dsn})
10
+ Object.defineProperty (dsn, '_4nodejs', {value:dsn})
11
+ return dsn
12
12
  }
@@ -1,16 +1,11 @@
1
1
  const compile = require ('../cdsc')
2
2
 
3
3
  module.exports = function cds_compile_for_odata (csn,_o) {
4
- if (_is_odata(csn)) return csn
5
- let {_4odata} = csn; if (!_4odata) {
6
- const o = compile._options.for.odata(_o) //> required to inspect .sql_mapping below
7
- _4odata = compile.for.odata (csn,o)
8
- // cache result for subsequent uses
9
- Object.defineProperty (csn, '_4odata', { value: _4odata, configurable:1, writable:1 })
10
- // compatibility with csn.json for old Java stack
11
- if (o.sql_mapping) _4odata['@sql_mapping'] = o.sql_mapping
12
- }
13
- return _4odata
4
+ if ('_4odata' in csn) return csn._4odata
5
+ let o = compile._options.for.odata(_o) //> required to inspect .sql_mapping below
6
+ let dsn = compile.for.odata (csn,o)
7
+ if (o.sql_mapping) dsn['@sql_mapping'] = o.sql_mapping //> compat4 old Java stack
8
+ Object.defineProperty (csn, '_4odata', {value:dsn})
9
+ Object.defineProperty (dsn, '_4odata', {value:dsn})
10
+ return dsn
14
11
  }
15
-
16
- const _is_odata = csn => csn.meta && csn.meta.transformation === 'odata'
@@ -1,10 +1,9 @@
1
- /** REVISIT: uses internal APIs to restore compile.for.sql in SNAPI */
2
- const compile = require ('@sap/cds-compiler/lib/backends')
1
+ /** REVISIT: Use `@sap/cds-compiler` if for_sql is made public. */
2
+ const compile = require ('@sap/cds-compiler/lib/api/main')
3
3
  let _compile
4
4
 
5
5
  module.exports = function cds_compile_for_sql (src,o) {
6
- _compile = _compile || compile.toSqlWithCsn || compile.for_sql
7
- // for_sql directly returns a CSN and not an object with a csn property
8
- const res = _compile(src,{...o,csn:true})
9
- return res.csn || res
6
+ _compile = _compile || compile.for_sql
7
+ // for_sql directly returns a CSN
8
+ return _compile(src,{...o,csn:true});
10
9
  }
@@ -20,6 +20,7 @@ const compile = module.exports = Object.assign (cds_compile, {
20
20
  csn: cds_compile,
21
21
  cdl: require('./to/cdl'),
22
22
  gql: require('./to/gql'),
23
+ graphql: require('./to/gql'),
23
24
  yml: require('./to/yaml'),
24
25
  yaml: require('./to/yaml'),
25
26
  json: require('./to/json'),
@@ -62,7 +63,7 @@ function cds_compile (model, options, _flavor) {
62
63
  // REVISIT: experimental implementation to detect external APIs
63
64
  for (let each in csn.definitions) {
64
65
  const d = csn.definitions[each]
65
- if (d.kind === 'service' && cds.requires[each] && (!o.mocked || cds.requires[each].credentials)) {
66
+ if (d.kind === 'service' && cds.requires[each]?.external && (!o.mocked || cds.requires[each].credentials)) {
66
67
  Object.defineProperty (d,'@cds.external', { value: cds.requires[each].kind || true })
67
68
  }
68
69
  }
@@ -75,7 +76,7 @@ function cds_compile (model, options, _flavor) {
75
76
 
76
77
  const _is_csn = (x) => (x.definitions || x.extensions) && !x.$builtins
77
78
  const _is_files = m => {
78
- if (Array.isArray(m) || /file:/.test(m) && (m = m.slice(5)))
79
+ if (Array.isArray(m) || /^file:/.test(m) && (m = m.slice(5)))
79
80
  return cds.resolve(m) || cds.error ( `Couldn't find a CDS model for '${m}' in ${cds.root}`,{ code:'MODEL_NOT_FOUND', model: m })
80
81
  }
81
82
  const _assert_flavor = (m,_flavor,options) => {
@@ -85,7 +86,7 @@ const _assert_flavor = (m,_flavor,options) => {
85
86
 
86
87
  const _flavors = {
87
88
  'parsed': { level:1, cdsc_options: { parseCdl:true } },
88
- 'xtended': { level:2, cdsc_options: { toCsn:{flavor:'gensrc'} } },
89
+ 'xtended': { level:2, cdsc_options: { csnFlavor:'gensrc' } },
89
90
  'inferred': { level:3 },
90
91
  }
91
92
  const _flavor4 = (o) => {
@@ -95,7 +96,7 @@ const _flavor4 = (o) => {
95
96
  const _options4 = (_o, _flavor) => {
96
97
  const flavor = _flavor ? _flavor4(_flavor) : _flavor4(_o) || 'inferred'
97
98
  const spec = _flavors[flavor]
98
- const o = { ..._o, flavor, ...spec.cdsc_options, ...cds.env.cdsc }
99
+ const o = { ..._o, flavor, ...spec.cdsc_options, ...cds.env.cdsc, cdsHome: cds.home } // cdsHome is for the compiler resolving @sap/cds/... files
99
100
  if (o.docs) o.docComment = true
100
101
  if (o.locations) o.withLocations = true
101
102
  if (!o.messages) o.messages = []
@@ -1,16 +1,17 @@
1
1
  const cds = require('..')
2
2
 
3
3
 
4
- function cds_load (files, options) {
4
+ module.exports = exports = function cds_load (files, options) {
5
5
  const all = cds.resolve(files,options)
6
- if (!all) return cds.error.reject (
7
- `Couldn't find a CDS model for '${files}' in ${cds.root}`, { code:'MODEL_NOT_FOUND', files }
8
- )
6
+ if (!all) return Promise.reject (new cds.error ({
7
+ message: `Couldn't find a CDS model for '${files}' in ${cds.root}`,
8
+ code: 'MODEL_NOT_FOUND', files,
9
+ }))
9
10
  return this.get (all,options,'inferred')
10
11
  }
11
12
 
12
13
 
13
- function cds_get (files, options, _flavor) { // NOSONAR
14
+ exports.parsed = function cds_get (files, options, _flavor) { // NOSONAR
14
15
 
15
16
  const o = typeof options === 'string' ? { flavor:options } : options || {}
16
17
  if (!files) files = ['*']; else if (!Array.isArray(files)) files = [files]
@@ -39,9 +40,6 @@ const _sources4 = async (files) => {
39
40
  return files.reduce ((all,f,i) => { all[relative(cwd,f)] = sources[i]; return all },{})
40
41
  }
41
42
 
42
- module.exports = Object.assign (cds_load, {
43
- parsed: cds_get,
44
- properties: (...args) => (cds_load.properties = require('./etc/properties').read) (...args),
45
- yaml: (file) => (cds_load.yaml = require('./etc/yaml').read) (file),
46
- csv: (file) => (cds_load.csv = require('./etc/csv').read) (file),
47
- })
43
+ exports.properties = (...args) => (exports.properties = require('./etc/properties').read) (...args)
44
+ exports.yaml = (file) => (exports.yaml = require('./etc/yaml').read) (file)
45
+ exports.csv = (file) => (exports.csv = require('./etc/csv').read) (file)
@@ -1,11 +1,14 @@
1
- module.exports = function cds_minify (csn, _roots = global.cds.env.features.skip_unused) {
2
- if (_roots === false) return csn
1
+ const cds = require('../index')
2
+
3
+ module.exports = function cds_minify (csn, _roots) { // IMPORTANT: don't add cds.env.features.skip_unused as default for _roots here, as that will break VSCode's IntelliSense
4
+ const roots = _roots !== undefined ? _roots : cds.env.features.skip_unused
5
+ if (roots === false) return csn
3
6
  if (csn[_minified]) return csn; else Object.defineProperty (csn,_minified,{value:true})
4
7
  const all = csn.definitions, reached = new Set
5
- if (_roots === 'services') {
8
+ if (roots === 'services') {
6
9
  for (let n in all) if (all[n].kind === 'service') _visit_service(n)
7
- } else if (typeof _roots === 'string') {
8
- _visit_service(_roots)
10
+ } else if (typeof roots === 'string') {
11
+ _visit_service(roots)
9
12
  } else for (let n in all) {
10
13
  let d = all[n]
11
14
  if (d.kind === 'service') _visit_service(n)
@@ -28,10 +28,10 @@ const parse = module.exports = Object.assign (cds_parse, {
28
28
  }
29
29
  else return parse.expr(x)
30
30
  },
31
- expr: x => {
31
+ expr: (x,o) => {
32
32
  if (typeof x !== 'string') throw cds.error.expected `${{x}} to be an expression string`
33
33
  if (x in keywords) return {ref:[x]}
34
- try { return cdsc.parse.expr(x,undefined,{messages:[]}) } catch(e) {
34
+ try { return cdsc.parse.expr(x,undefined,{ messages:[], ...o }) } catch(e) {
35
35
  e.message = e.message.replace('<expr>.cds:1:',`In '${e.expr = x}' at `)
36
36
  throw e // with improved error message
37
37
  }
@@ -49,6 +49,7 @@ const parse = module.exports = Object.assign (cds_parse, {
49
49
 
50
50
  const tagged = (parse, strings, ...values) => {
51
51
  if (!strings.raw) return parse (strings, ...values)
52
+ if (!strings.length) return parse (strings[0])
52
53
  const all = new Array (strings.length + values.length)
53
54
  for (var i=0; i<strings.length-1; ++i) {
54
55
  let v = values[i], s = strings[i]
@@ -64,6 +65,7 @@ const tagged = (parse, strings, ...values) => {
64
65
  const merge = (o,values) => {
65
66
  for (let k in o) {
66
67
  const x = o[k]
68
+ if (!x) continue
67
69
  if (x.param) {
68
70
  let val = values[x.ref[0]]; if (val === undefined) continue
69
71
  let y = o[k] = cxn4(val)
@@ -25,7 +25,7 @@ module.exports = exports = function cds_resolve (model, o={}) { // NOSONAR
25
25
  if (model.endsWith('/*')) return _resolve_subdirs_in(model,o,this)
26
26
 
27
27
  const cwd = o.root || this.root, local = resolve (cwd,model)
28
- const context = _paths(cwd), {cached} = context
28
+ const context = _paths(cwd,o), {cached} = context
29
29
  let id = model.startsWith('.') ? local : model
30
30
  if (id in cached) return cached[id]
31
31
 
@@ -65,37 +65,40 @@ module.exports = exports = function cds_resolve (model, o={}) { // NOSONAR
65
65
  exports.cache = {}
66
66
 
67
67
 
68
- const _required = cds => Object.values(cds.env.requires) .map (r => r.model) .filter(x=>x)
68
+ const _required = (cds,env=cds.env) => Object.values(env.requires) .map (r => r.model) .filter(x=>x)
69
69
  const _resolve = require('module')._resolveFilename
70
70
 
71
71
  function _resolve_all (o,cds) {
72
- const {roots} = cds.env; if (o.dry || o === false) return [ ...roots, ..._required(cds) ]
73
- const cached = exports.cache['*']; if (cached) return cached
74
- exports.cache['*'] = [] // important to avoid endless recursion on '*'
72
+ const {roots} = o.env || cds.env; if (o.dry || o === false) return [ ...roots, ..._required(cds) ]
73
+ const cache = o.cache || exports.cache
74
+ const cached = cache['*']; if (cached) return cached
75
+ cache['*'] = [] // important to avoid endless recursion on '*'
75
76
  const sources = cds.resolve (roots,o) || []
76
77
  if (!(sources.length === 1 && sources[0].endsWith('csn.json'))) // REVISIT: why is that? -> pre-compiled gen/csn.json?
77
- sources.push (...cds.resolve (_required(cds),o)||[])
78
- return exports.cache['*'] = _resolved (sources)
78
+ sources.push (...cds.resolve (_required(cds,o.env),o)||[])
79
+ return cache['*'] = _resolved (sources)
79
80
  }
80
81
 
81
82
  function _resolve_subdirs_in (pattern='fts/*',o,cds) {
82
- const cached = exports.cache[pattern]; if (cached && !o.dry && o !== false) return cached
83
- const folder = pattern.slice(0,-2), dir = resolve (cds.root, folder)
83
+ const cache = o.cache || exports.cache
84
+ const cached = cache[pattern]; if (cached && !o.dry && o !== false) return cached
85
+ const folder = pattern.slice(0,-2), dir = resolve (o.root || cds.root, folder)
84
86
  try {
85
- const dirs = readdirSync(dir) .map (e => folder+'/'+e+'/') .filter (cds.utils.isdir)
87
+ const dirs = readdirSync(dir) .filter (e => cds.utils.isdir(dir+sep+e)) .map (e => folder+sep+e+sep)
86
88
  if (o.dry || o === false) return dirs
87
- return exports.cache[pattern] = cds.resolve (dirs,o) || undefined
89
+ return cache[pattern] = cds.resolve (dirs,o) || undefined
88
90
  } catch(e) {
89
91
  if (e.code === 'ENOENT')
90
- return exports.cache[pattern] = undefined
92
+ return cache[pattern] = undefined
91
93
  }
92
94
  }
93
95
 
94
- function _paths (dir) {
95
- const cached = exports.cache[dir]; if (cached) return cached
96
+ function _paths (dir,o) {
97
+ const cache = o.cache || exports.cache
98
+ const cached = cache[dir]; if (cached) return cached
96
99
  const a = dir.split(sep), n = a.length, nm = sep+'node_modules'
97
100
  const paths = [ dir, ...a.map ((_,i,a)=> a.slice(0,n-i).join(sep)+nm) ]
98
- return exports.cache[dir] = { paths, cached:{} }
101
+ return cache[dir] = { paths, cached:{} }
99
102
  }
100
103
 
101
104
  function _resolved (array) {
@@ -55,5 +55,4 @@ function* _many (suffix, all, callback = x=>x) {
55
55
  for (let file in all) yield [ callback(all[file]), { file, suffix } ]
56
56
  }
57
57
 
58
-
59
58
  module.exports = Object.assign (cds_compile_to_edm, { x: cds_compile_to_edmx })
@@ -1,9 +1,10 @@
1
- const { generate } = require ('../../../libx/gql/schema')
2
1
  const cds = require ('../..')
2
+ const { SchemaGenerator } = require('@sap/cds-graphql/lib/schema')
3
3
 
4
4
  function cds_compile_to_gql (csn) {
5
5
  const m = cds.linked(csn)
6
- return generate (m.services.map(s => ({ name:s.name, model:m })))
6
+ const services = Object.fromEntries(m.services.map(s => [s.name, new cds.ApplicationService(s.name, m)]))
7
+ return new SchemaGenerator().generate(services).printSchema()
7
8
  }
8
9
 
9
10
  module.exports = cds_compile_to_gql
@@ -1,25 +1,32 @@
1
1
  const cds = require ('../../index')
2
-
3
2
  const path = require('path')
4
3
 
5
- module.exports = (csn,o={}) => JSON.stringify (csn, (_,v) => {
4
+ module.exports = (csn,o={}) => {
5
+ const relative = filename => (o.src !== o.cwd) ? path.relative(o.src, path.join(o.cwd, filename)) : filename
6
+ const relative_cds_home = RegExp ('^' + path.relative (o.src || o.cwd || cds.root, cds.home) + '/')
7
+ const resolver = (_,v) => {
6
8
 
7
- if (!v) return v
9
+ if (!v) return v
8
10
 
9
- else if (v.grant && v.where) try {
10
- // Add a parsed _where clause for @restrict.{grant,where} annotations
11
- // Note: This has moved to cds.compile.for.java meanwhile, but is kept
12
- // here for compatibility, at least temporarily.
13
- return {...v, _where: JSON.stringify (cds.parse.xpr(v.where)) }
14
- } catch(e){/* ignored */}
11
+ else if (v.grant && v.where) try {
12
+ // Add a parsed _where clause for @restrict.{grant,where} annotations
13
+ // Note: This has moved to cds.compile.for.java meanwhile, but is kept
14
+ // here for compatibility, at least temporarily.
15
+ return {...v, _where: JSON.stringify (cds.parse.xpr(v.where)) }
16
+ } catch(e){/* ignored */}
15
17
 
16
- else if (v.kind === "service" && !v['@source'] && v.$location && v.$location.file) {
17
- // Preserve original sources for services so we can use them for finding
18
- // sibling implementation files when reloaded from csn.json.
19
- const file = (o.cwd !== o.src) ? path.relative(o.src, path.join(o.cwd, v.$location.file)) : v.$location.file
20
- return { '@source': file.replace(/\\/g,'/'), ...v }
21
- }
18
+ else if (v.kind === "service" && !v['@source'] && v.$location?.file) {
19
+ // Preserve original sources for services so we can use them for finding
20
+ // sibling implementation files when reloaded from csn.json.
21
+ const file = relative(v.$location.file)
22
+ .replace(relative_cds_home,'@sap/cds/')
23
+ .replace('node_modules/','')
24
+ .replace(/\\/g,'/')
25
+ return { '@source': file, ...v }
26
+ }
22
27
 
23
- return v
28
+ return v
24
29
 
25
- }, o && o.indents || 2)
30
+ }
31
+ return JSON.stringify (csn, resolver, o && o.indents || 2)
32
+ }
@@ -41,7 +41,8 @@ module.exports = class Bindings {
41
41
  const required = cds.requires; if (!required) return this
42
42
  const provided = (await this.load()) .cds.provides
43
43
  for (let each in required) {
44
- const req = required[each], bound = provided [req.service||each]
44
+ const req = required[each]; if (typeof req !== 'object') continue
45
+ const bound = provided [req.service||each]
45
46
  if (bound) {
46
47
  Object.assign (req.credentials || (req.credentials = {}), bound.credentials)
47
48
  // REVISIT: temporary fix to inherit kind as well for mocked odata services
@@ -67,7 +68,7 @@ module.exports = class Bindings {
67
68
  }
68
69
  }
69
70
  }
70
- process.on ('exit', ()=>this.purge())
71
+ cds.on ('shutdown', ()=>this.purge())
71
72
  return this.store()
72
73
  }
73
74
 
@@ -28,9 +28,9 @@ connect.to = async (datasource, options) => {
28
28
  if (!options) { //> specifying ad-hoc options disallows caching
29
29
  if (datasource in cds.services) return cds.services[datasource]
30
30
  if (datasource in _pending) return _pending[datasource]
31
+ // queue parallel requests to a single promise, to avoid creating multiple services
32
+ _pending[datasource] = new Promise (r=>_done=r).finally(()=> delete _pending[datasource])
31
33
  }
32
- // queue parallel requests to a single promise, to avoid creating multiple services
33
- _pending[datasource] = new Promise (r=>_done=r).finally(()=>{ delete _pending[datasource] })
34
34
  }
35
35
  const o = Service === cds.service.factory ? options4 (datasource, options) : {}
36
36
  const m = await model4 (o)
@@ -41,7 +41,7 @@ connect.to = async (datasource, options) => {
41
41
  throw new Error (`No service definition found for '${required.service || datasource}'`)
42
42
  }
43
43
  // construct new service instance
44
- const srv = new Service (datasource,m,o)
44
+ const srv = await new Service (datasource,m,o)
45
45
  await srv.prepend (srv.init, srv.options.impl)
46
46
  if (datasource === 'db') cds.db = srv
47
47
  _done (cds.services[datasource] = srv)
@@ -51,11 +51,11 @@ connect.to = async (datasource, options) => {
51
51
 
52
52
  function options4 (name, _o) {
53
53
  const [, kind=_o && _o.kind, url] = /^(\w+):(.*)/.exec(name) || []
54
- const conf = cds.requires[name] || cds.requires[kind]
54
+ const conf = cds.requires[name] || cds.requires[kind] || cds.requires.kinds[name] || cds.requires.kinds[kind]
55
55
  const o = { kind, ...conf, ..._o }
56
56
  if (!o.kind && !o.impl && !o.silent) throw cds.error(
57
57
  conf ? `Configuration for 'cds.requires.${name}' lacks mandatory property 'kind' or 'impl'` :
58
- name ? `Didn't find a configuration for 'cds.requires.${name}'` :
58
+ name ? `Didn't find a configuration for 'cds.requires.${name}' in ${cds.root}` :
59
59
  `Provided options object lacks mandatory property 'kind' or 'impl'`
60
60
  )
61
61
  if (url) o.credentials = { ...o.credentials, url }
@@ -9,15 +9,20 @@ class any {
9
9
  is (kind) { return this.kind === kind || kind === 'any' }
10
10
  valueOf() { return this.name }
11
11
 
12
- own (property) {
12
+ own (property, ifAbsent) {
13
13
  const pd = Reflect.getOwnPropertyDescriptor (this, property)
14
14
  if (pd) return pd.value //|| pd.get(this)
15
+ if (ifAbsent) return this.set (property, ifAbsent())
15
16
  }
16
17
 
17
18
  set (property, value, enumerable = false) {
18
19
  Reflect.defineProperty (this, property, { value, enumerable, writable:1, configurable:1 })
19
20
  return value
20
21
  }
22
+
23
+ dataIn (d, prefix='') {
24
+ return d[prefix + this.name]
25
+ }
21
26
  }
22
27
 
23
28
  class type extends any {}
@@ -47,9 +52,76 @@ class service extends context {
47
52
 
48
53
  class array extends type { is(kind) { return kind === 'array' || super.is(kind) }}
49
54
  class aspect extends type { is(kind) { return kind === 'aspect' || super.is(kind) }}
50
- class struct extends aspect { is(kind) { return kind === 'struct' || super.is(kind) }}
51
55
  class event extends aspect{}
52
56
 
57
+ class struct extends aspect {
58
+ is(kind) { return kind === 'struct' || super.is(kind) }
59
+
60
+ /**
61
+ * Gets the foreign key data for a given managed association from inbound data
62
+ * in structured form.
63
+ *
64
+ * @example
65
+ * let { Books } = srv.entities
66
+ * let { author } = Books.elements
67
+ * let book = { // inbound data, e.g. from req.data
68
+ * title: 'Foo',
69
+ * author_ID: 111
70
+ * }
71
+ * let value = author.dataIn(book)
72
+ * //> { ID: 111 }
73
+ *
74
+ * Actually this works for all struct-like elements, i.e., which's definitions
75
+ * have .elements or .foreignKeys. Could be added to cds.struct/cds.Association.
76
+ */
77
+ dataIn (d, prefix='', _skip_root) {
78
+ const key = prefix + this.name; if (!_skip_root && key in d) return d[key]
79
+ const elements = this.elements || this.foreignKeys // REVISIT: .foreignKeys should be .elements
80
+ const nested={}, key_ = _skip_root ? '' : key+'_'
81
+ let any; for (let e in elements) {
82
+ const v = elements[e] .dataIn (d,key_)
83
+ if (v !== undefined) nested[any=e] = v
84
+ }
85
+ if (any) return !prefix && d._hull ? d._hull[key] = nested : nested
86
+ }
87
+
88
+ /**
89
+ * Returns a Proxy for provided data which adds getters to return values
90
+ * for struct elements (including Associations) in structured form.
91
+ *
92
+ * @example
93
+ * let { Books } = m.entities
94
+ * let data = Books.data ({
95
+ * author: {ID:111},
96
+ * genre_ID: 22
97
+ * })
98
+ * console.log ('author:', data.author) //> { ID: 111 }
99
+ * console.log ('genre:', data.genre) //> { ID: 22 }
100
+ */
101
+ data (d) {
102
+ if (_proxy in d) return d[_proxy] //> use cached proxy, if exists
103
+
104
+ // hull to cache calculated values without polluting original input
105
+ const _hull = {__proto__:d}
106
+
107
+ // allow external code to access _hull
108
+ Object.defineProperty (_hull, '_hull', {value:_hull})
109
+
110
+ // proxy calls def.dataIn() for defined elements, fallback hull[p]
111
+ const {elements} = this, proxy = new Proxy (d, {
112
+ get: (_,p) => elements[p]?.dataIn(_hull) || _hull[p],
113
+ })
114
+
115
+ // cache proxy with original data
116
+ Object.defineProperty (d, _proxy, {value:proxy})
117
+
118
+ return proxy
119
+ }
120
+
121
+ }
122
+ const _proxy = Symbol('_proxy')
123
+
124
+
53
125
  /**
54
126
  * Export is a dictionary of all builtin classes
55
127
  */
@@ -1,4 +1,4 @@
1
- const { struct, type } = require ('./classes')
1
+ const { struct } = require ('./classes')
2
2
 
3
3
  class entity extends struct {
4
4
  is (kind) { return kind === 'entity' || kind === 'view' && !!this.query || super.is(kind) }
@@ -23,7 +23,8 @@ class entity extends struct {
23
23
  }
24
24
  }
25
25
 
26
- class Association extends type {
26
+
27
+ class Association extends struct {
27
28
 
28
29
  is(kind) { return kind === 'Association' || super.is(kind) }
29
30
  get isAssociation(){ return true }
@@ -41,7 +42,7 @@ class Association extends type {
41
42
  for (const k of keys) {
42
43
  const el = k.ref.reduce((target,n)=> target.elements[n], this._target)
43
44
  const as = k.as || k.ref[k.ref.length-1]
44
- foreignKeys [as] = el
45
+ foreignKeys [as] = el.name === as ? el : { __proto__:el, name:as }
45
46
  }
46
47
  return this.foreignKeys = foreignKeys
47
48
  }
@@ -53,7 +54,55 @@ class Association extends type {
53
54
  for (let k in tks) keys.push({ ref: [tks[k].name] })
54
55
  return this.keys = keys
55
56
  }
57
+
58
+ /**
59
+ * Gets the foreign key data for a given managed association from inbound data
60
+ * converted to an object that can be used as a where clause filter to fetch
61
+ * from the assoc's target entity. The function correctly handles renamed
62
+ * foreign keys.
63
+ *
64
+ * @example
65
+ * entity Books { //...
66
+ * author : Association to Authors { ID:id } // renamed foreign key
67
+ * }
68
+ *
69
+ * @example
70
+ * let { Books, Authors } = srv.entities
71
+ * let { author } = Books.elements
72
+ * let data = { // inbound data, e.g. from req.data
73
+ * title: 'Foo',
74
+ * author_id: 111
75
+ * }
76
+ * let entry = author.refIn(data)
77
+ * //> { ref: [ {id:'Authors', where:[ {ref:['ID']}, '=', {val:111} ]} ]}
78
+ * await SELECT.one(entry)
79
+ * await db.exists(entry)
80
+ */
81
+ refIn (d) {
82
+ if (!this.keys) throw new Error (`Can't collect filter data for unmanaged associations`)
83
+ const value = this.dataIn(d); if (!value) return
84
+ const where={}; for (let {ref:[r],as} of this.keys) where[r] = value[as||r]
85
+ const q = SELECT.from (this._target, where)
86
+ return q.SELECT.from
87
+ }
88
+
89
+ /**
90
+ * Overriding implementation in base class to handle data for to-many Associations.
91
+ */
92
+ dataIn (d, prefix='') {
93
+ if (this.is2many) {
94
+ const key = this.name, _key = '_'+key; if (_key in d) return d[_key]
95
+ const input = d[key]; if (input[_is_cached]) return input
96
+ if (Array.isArray(input)) {
97
+ const value = d[key].map (each => this._target.dataIn (each,'',true))
98
+ if (!prefix && d._hull) d._hull[key] = Object.defineProperty(value, _is_cached, {value:true})
99
+ return value
100
+ }
101
+ }
102
+ else return super.dataIn (d,prefix)
103
+ }
56
104
  }
105
+ const _is_cached = Symbol('_cached')
57
106
 
58
107
 
59
108
  class Composition extends Association {
@@ -25,6 +25,7 @@ class LinkedCSN extends any {
25
25
  /* else: */ any.prototype
26
26
  )
27
27
  if (p.key && !d.key && d.kind === 'element') Object.defineProperty (d,'key',{value:undefined}) //> don't propagate .key
28
+ if (p.params && !d.params && d.kind === 'entity') Object.defineProperty (d,'params',{value:undefined}) //> don't propagate .key
28
29
  if (d.elements && d.elements.localized) Object.defineProperty (d,'texts',{value: defs [d.elements.localized.target] })
29
30
  try { return Object.setPrototypeOf(d,p) } //> link d to resolved proto
30
31
  catch(e) { //> cyclic proto error
@@ -108,5 +109,5 @@ const _is = x => {
108
109
 
109
110
  /** @returns {LinkedCSN} */
110
111
  module.exports = x => x instanceof any ? x : new LinkedCSN (
111
- typeof x === 'string' ? global.cds.parse(x) : x
112
+ typeof x === 'string' ? require('../index').compile(x) : x
112
113
  )