@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
package/lib/deploy.js CHANGED
@@ -12,6 +12,7 @@ exports = module.exports = function cds_deploy (model,options) { return {
12
12
 
13
13
  /** @param {cds.Service} db */
14
14
  async to (db, o = options || cds.options || {}) {
15
+ if (!model) throw new Error('Must provide a model or a path to model, received: ' + model)
15
16
  const LOG = o.silent || !cds.log('deploy')._info ? ()=>{} : console.log
16
17
 
17
18
  if (model && !model.definitions) {
@@ -110,7 +111,7 @@ exports.create = async function (db, csn=db.model, o) {
110
111
  console.log(); for (let each of drops) console.log(each)
111
112
  console.log(); for (let each of creates) console.log(each,'\n')
112
113
  return
113
- } else await db.tx (async tx => {
114
+ } else return db.tx (async tx => {
114
115
  await tx.run(drops)
115
116
  await tx.run(creates)
116
117
  return true
@@ -120,21 +121,23 @@ exports.create = async function (db, csn=db.model, o) {
120
121
 
121
122
 
122
123
  exports.init = (db, csn=db.model, log=()=>{}) => db.tx (async tx => {
123
- cds.context = tx //> registers tx as root transaction
124
- const resources = await exports.resources(csn), inits=[], err = new Error
124
+ const resources = await exports.resources(csn), inits=[]
125
125
  for (let [file,e] of Object.entries(resources)) {
126
126
  if (e === '*') { // init.js/ts
127
- const x = require(file); if (!x) continue
127
+ const { pathToFileURL } = require('url') // on Windows, must use a file: URL for ESM import
128
+ let x = typeof jest !== 'undefined' ? require(file) : await import(pathToFileURL(file).href); if (!x) continue
129
+ if (x.default) x = x.default // default ESM export
130
+ inits.push (!x.then && typeof x === 'function' ? x(db,csn) : x)
128
131
  log (file)
129
- inits.push (!x.then && typeof x === 'function' ? x(db) : x)
130
132
  } else { // from .csv or .json
131
133
  const INSERT_into = _from_csv_or_json [path.extname(file)]
132
134
  const src = await read(file,'utf8'); if (!src) continue
133
135
  const q = INSERT_into (e,src); if (!q) continue
134
136
  log (file,e)
135
- inits.push (tx.run(q) .catch (e => { throw Object.assign (e,{
136
- message: 'in cds.deploy(): ' + e.message +'\n'+ inspect(q),
137
- })}))
137
+ inits.push (tx.run(q) .catch (e => {
138
+ Error.captureStackTrace(e)
139
+ throw Object.assign (e, { message: 'in cds.deploy(): ' + e.message +'\n'+ inspect(q) })
140
+ }))
138
141
  }
139
142
  }
140
143
  await Promise.all (inits)
@@ -20,10 +20,9 @@ module.exports = {
20
20
  skip_unused: true,
21
21
  one_model: true,
22
22
  localized: true,
23
- assert_integrity: true,
24
- assert_integrity_type: 'RT',
23
+ assert_integrity: false,
25
24
  cds_tx_protection: true,
26
- cds_tx_inheritance: true,
25
+ cds_tx_inheritance: true
27
26
  },
28
27
 
29
28
  log: {
@@ -53,11 +52,13 @@ module.exports = {
53
52
  },
54
53
 
55
54
  i18n: {
55
+ file: 'i18n', // file basename w/o extension
56
56
  folders: ['_i18n', 'i18n', 'assets/i18n'],
57
57
  for_sqlite: ['de', 'fr'],
58
58
  for_sql: ['de', 'fr'],
59
59
  languages: 'all', // or array. 'all': whatever language files are found next to models
60
60
  default_language: 'en',
61
+ fallback_bundle: '',
61
62
  preserved_locales: [
62
63
  // IMPORTANT: Never, never modify this list, as that would break existing projects !!!!
63
64
  // Projects can and have to override if they want something different.
package/lib/env/index.js CHANGED
@@ -2,6 +2,7 @@ const { isfile, fs, path } = require('../utils')
2
2
  const DEFAULTS = require('./defaults'), defaults = require.resolve ('./defaults')
3
3
  const compat = require('./compat')
4
4
  const presets = require('./presets')
5
+ const serviceBindings = require('./serviceBindings');
5
6
 
6
7
 
7
8
  /**
@@ -16,7 +17,7 @@ class Config {
16
17
  * @returns {Config & typeof DEFAULTS}
17
18
  */
18
19
  for (context, cwd, _defaults=true) {
19
- if (!cwd) cwd = global.cds && global.cds.root || process.cwd()
20
+ if (!cwd) cwd = this._home || require('..').root || process.cwd()
20
21
  return new Config (context, cwd, _defaults)
21
22
  }
22
23
 
@@ -63,14 +64,17 @@ class Config {
63
64
  }
64
65
  }
65
66
 
66
- // 4. add process env
67
+ // 4. link dependant services (through kind/use)
68
+ this._link_required_services()
69
+
70
+ // 5. add process env
67
71
  this._add_process_env(_context, _home)
68
72
 
69
- // 6. link dependant services (through kind/use)
73
+ // 6. link dependant services again -> e.g. to allow things like CDS_requires_db=sql
70
74
  this._link_required_services()
71
75
 
72
- // 7. complete service configurations from VCAP
73
- this._add_vcap_services (process.env.VCAP_SERVICES)
76
+ // 7. complete service configurations from cloud service bindings
77
+ this._add_cloud_service_bindings({ VCAP_SERVICES: process.env.VCAP_SERVICES, SERVICE_BINDING_ROOT: process.env.SERVICE_BINDING_ROOT })
74
78
 
75
79
  // 8. Add compatibility for mtx
76
80
  if (this.requires && this.requires.db) {
@@ -128,11 +132,12 @@ class Config {
128
132
 
129
133
  /**
130
134
  * This is `this.requires` plus additional entries for all cds.required.<name>.service
135
+ * @returns {import('./requires')}
131
136
  */
132
137
  get required_services_or_defs() {
133
138
  const dict = Object.create (this.requires)
134
139
  for (let [name,e] of Object.entries (this.requires)) if (e.service) {
135
- if (e.service in dict && e.service !== name) {
140
+ if (e.service in dict && !e.override && e.service !== name) {
136
141
  console.error (`Datasource name '${e.service}' conflicts with 'service' definition referred to in 'cds.requires.${name}':`, e)
137
142
  throw new Error (`Datasource name '${e.service}' conflicts with service definition`)
138
143
  }
@@ -242,6 +247,7 @@ class Config {
242
247
  for (var o=config,next;;) {
243
248
  next = path.shift()
244
249
  if (!path.length) break
250
+ if (!path[0]) next = next+'-'+path.shift()+path.shift() // foo__bar -> foo-bar
245
251
  o = o[next] || (o[next] = {})
246
252
  }
247
253
  o[next] = _value4(env[p])
@@ -252,31 +258,36 @@ class Config {
252
258
 
253
259
  _link_required_services () {
254
260
  const { requires } = this; if (!requires) return
255
- const kinds = requires.kinds
256
- if (kinds) {
257
- Object.defineProperty (requires, 'kinds', { value:kinds, enumerable:false }) // for cds env
258
- Object.setPrototypeOf (requires, kinds)
259
- for (let each in kinds) kinds[each] = _linked(each)
260
- }
261
- for (let each of Object.keys(requires)) {
262
- const e = requires[each] = _linked(each)
263
- if (!e) delete requires[each] // skip invalid values
264
- }
265
- function _linked (key) {
266
- const e = requires[key]; if (!e || e._is_linked || e.kind === key) return e
267
- let linked
268
- if (e === true) {
269
- if (key in kinds) linked = kinds[key]
270
- else return e
261
+ const kinds = requires.kinds || {}
262
+ Object.defineProperty (requires, 'kinds', { value:kinds, enumerable:false }) // for cds env
263
+ // Object.setPrototypeOf (requires, kinds)
264
+ for (let each in kinds) kinds[each] = _linked (each, kinds[each])
265
+ for (let each in requires) requires[each] = _linked (each, requires[each])
266
+ function _linked (key, val) {
267
+ if (!val || val._is_linked) return val
268
+ if (val === true) {
269
+ let x = kinds[key]
270
+ if (!x) return val
271
+ else val = x
272
+ }
273
+ if (typeof val === 'string') {
274
+ let x = kinds[val] || kinds[val+'-'+key] || kinds[key+'-'+val]
275
+ if (!x) return val
276
+ else val = { kind: val }
271
277
  }
272
- else if (e.kind in requires) {
273
- linked = _merge ({}, _linked(e.kind)) // first apply inherited data
274
- const {kind} = linked // get the kind from prototype
275
- _merge (linked, e, false, false) // then apply overridden data
276
- if (kind) linked.kind = kind // inherited kind wins
278
+ const preset1 = kinds[key]
279
+ if (typeof preset1 === 'object' && preset1 !== val) {
280
+ const top = val, base = _merge ({},_linked(key,preset1)), {kind} = base
281
+ val = _merge (base, top, false, false) // apply/override with top-level data
282
+ if (kind) val.kind = kind // but inherited kind wins
277
283
  }
278
- else linked = e
279
- return Object.defineProperty (linked, '_is_linked', {value:true})
284
+ let k = val.kind, p, preset = k && kinds[p=k] || kinds[p=k+'-'+key] || kinds[p=key+'-'+k]
285
+ if (typeof preset === 'object' && preset !== val) {
286
+ const top = val, base = _merge ({},_linked(p,preset)), {kind} = base
287
+ val = _merge (base, top, false, false) // apply/override with top-level data
288
+ if (kind) val.kind = kind // but inherited kind wins
289
+ }
290
+ return Object.defineProperty (val, '_is_linked', {value:true})
280
291
  }
281
292
  }
282
293
 
@@ -293,6 +304,34 @@ class Config {
293
304
  }
294
305
  }
295
306
 
307
+ _add_cloud_service_bindings({ VCAP_SERVICES, SERVICE_BINDING_ROOT }) {
308
+ let bindings, bindingsSource
309
+
310
+ if (!this.requires) return
311
+ if (VCAP_SERVICES && !(this.features && this.features.vcaps == false)) {
312
+ try {
313
+ bindings = JSON.parse(VCAP_SERVICES)
314
+ bindingsSource = '{VCAP_SERVICES}'
315
+ } catch(e) {
316
+ throw new Error ('[cds.env] - failed to parse VCAP_SERVICES:\n '+ e.message)
317
+ }
318
+ }
319
+
320
+ if (!bindings && SERVICE_BINDING_ROOT) {
321
+ bindings = serviceBindings(SERVICE_BINDING_ROOT)
322
+ bindingsSource = SERVICE_BINDING_ROOT
323
+ }
324
+
325
+ if (bindings) {
326
+ try {
327
+ const any = this._add_vcap_services_to(bindings)
328
+ if (any) this._sources.push(bindingsSource)
329
+ } catch(e) {
330
+ throw new Error(`[cds.env] - failed to add service bindings from ${bindingsSource}:\n ${e.message}`);
331
+ }
332
+ }
333
+ }
334
+
296
335
  /**
297
336
  * Build VCAP_SERVICES for compatibility (for example for CloudSDK) or for running
298
337
  * locally with credentials (hybrid mode).
@@ -347,7 +386,8 @@ class Config {
347
386
  _fetch ({ name: service }) ||
348
387
  _fetch ({ tag: this._context+':'+service }) ||
349
388
  _fetch ({ tag: conf.dialect || conf.kind }) || // important for hanatrial, labeled 'hanatrial', tagged 'hana'
350
- _fetch ({ label: conf.dialect || conf.kind })
389
+ _fetch ({ label: conf.dialect || conf.kind }) ||
390
+ _fetch ({ type: conf.dialect || conf.kind })
351
391
 
352
392
  function _fetch (predicate) {
353
393
  for (let k of Object.keys(predicate).reverse()) {
@@ -493,5 +533,5 @@ function _readFromDir (p, isDir) {
493
533
 
494
534
 
495
535
  /** @type Config & typeof DEFAULTS */
496
- module.exports = Config.prototype.for('cds')
536
+ module.exports = Config.prototype
497
537
  /* eslint no-console:0 */
@@ -6,9 +6,6 @@ module.exports = function (conf) {
6
6
  // integrity checks
7
7
  if (typeof features.assert_integrity === 'string') {
8
8
  switch (features.assert_integrity) {
9
- case 'individual':
10
- // > keep as is
11
- break
12
9
  case 'off':
13
10
  features.assert_integrity = false
14
11
  break
@@ -20,19 +17,9 @@ module.exports = function (conf) {
20
17
  features.assert_integrity = true
21
18
  features.assert_integrity_type = 'DB'
22
19
  break
23
- // *-opt-in options not officially documented!
24
- case 'app-opt-in':
25
- features.assert_integrity = 'individual'
26
- features.assert_integrity_type = 'RT'
27
- break
28
- case 'db-opt-in':
29
- features.assert_integrity = 'individual'
30
- features.assert_integrity_type = 'DB'
31
- break
32
20
  default:
33
21
  // > invalid -> set to default
34
- features.assert_integrity = true
35
- features.assert_integrity_type = 'RT'
22
+ features.assert_integrity = false
36
23
  }
37
24
  }
38
25
 
@@ -16,18 +16,22 @@ exports = module.exports = {
16
16
 
17
17
  const _authentication_strategies = {
18
18
 
19
- "dummy-auth": {
20
- strategy: 'dummy',
21
- },
22
- "basic-auth": {
23
- kind: "mocked-auth"
24
- },
19
+ "basic-auth": "mocked-auth",
25
20
  "mocked-auth": {
26
21
  strategy: 'mock',
27
22
  users: {
28
23
  alice: { roles: ['admin'] },
29
- bob: { roles: ['builder'] },
24
+ bob: { roles: ['builder'] },
25
+ carol: { tenant: 't1', roles: ['admin', 'cds.Subscriber', 'cds.ExtensionDeveloper', 'cds.UIFlexDeveloper'] },
26
+ dave: { tenant: 't1', roles: ['cds.Subscriber'], features: [] }, // user-specific features
27
+ erin: { tenant: 't2', roles: ['admin', 'cds.Subscriber', 'cds.ExtensionDeveloper'] },
28
+ fred: { tenant: 't2', roles: [], features: ['isbn'] },
29
+ yves: { roles: ['internal-user'] },
30
30
  '*': true
31
+ },
32
+ tenants: {
33
+ t1: { features: [ 'isbn' ], }, // tenant-specific features
34
+ t2: { features: '*', },
31
35
  }
32
36
  },
33
37
  "jwt-auth": {
@@ -38,6 +42,9 @@ const _authentication_strategies = {
38
42
  strategy: 'xsuaa',
39
43
  vcap: { label: 'xsuaa' }
40
44
  },
45
+ "dummy-auth": {
46
+ strategy: 'dummy',
47
+ },
41
48
 
42
49
  }
43
50
 
@@ -49,16 +56,24 @@ const _services = {
49
56
  impl: `${_runtime}/cds-services/services/Service.js`
50
57
  },
51
58
  "rest": {
52
- impl: `${_runtime}/remote/Service.js`
59
+ impl: `${_runtime}/remote/Service.js`,
60
+ external: true
53
61
  },
54
62
  "odata": {
55
- impl: `${_runtime}/remote/Service.js`
63
+ impl: `${_runtime}/remote/Service.js`,
64
+ external: true
56
65
  },
57
66
  "odata-v2": { // REVISIT: we should introduce .version
58
- impl: `${_runtime}/remote/Service.js`
67
+ impl: `${_runtime}/remote/Service.js`,
68
+ external: true
59
69
  },
60
70
  "odata-v4": { // REVISIT: we should introduce .version
61
- impl: `${_runtime}/remote/Service.js`
71
+ impl: `${_runtime}/remote/Service.js`,
72
+ external: true
73
+ },
74
+ "graphql": { // REVISIT: we should introduce .version
75
+ impl: `${_runtime}/remote/Service.js`,
76
+ external: true
62
77
  },
63
78
 
64
79
  }
@@ -99,7 +114,7 @@ const _messaging = {
99
114
  "file-based-messaging": {
100
115
  outbox: {},
101
116
  impl: `${_runtime}/messaging/file-based.js`,
102
- credentials: { file:'~/.cds-msg-box' }
117
+ file:'~/.cds-msg-box'
103
118
  },
104
119
  "default-messaging": {
105
120
  "[development]": { kind: "local-messaging" },
@@ -148,21 +163,57 @@ const _messaging = {
148
163
  "persistent-outbox": {
149
164
  model: "@sap/cds/srv/outbox",
150
165
  maxAttempts: 20,
151
- chunkSize: 100
166
+ chunkSize: 100,
167
+ storeLastError: true
152
168
  },
153
169
 
154
170
  }
155
171
 
156
172
 
157
- const _multitenancy = {
158
- }
173
+ const _mtx_services = {
159
174
 
175
+ "toggles": {
176
+ model: "@sap/cds/srv/mtx"
177
+ },
178
+ "cds.xt.ModelProviderService": {
179
+ model: "@sap/cds/srv/model-provider"
180
+ },
181
+ "cds.xt.ModelProviderService-in-sidecar": {
182
+ "[development]": { root: "../.." }, // sidecar is expected to reside in ./mtx/sidecar
183
+ "[production]": { root: "_main" },
184
+ "[prod]": { root: "_main" }, // for simulating production in local tests
185
+ },
186
+ "cds.xt.ModelProviderService-from-sidecar": {
187
+ kind: 'rest'
188
+ },
160
189
 
161
- const _extensibility = {
190
+ "multitenancy": {
191
+ model: "@sap/cds/srv/mtx",
192
+ kind: "saas-registry",
193
+ },
194
+ "cds.xt.SaasProvisioningService": {
195
+ model: "@sap/cds-mtxs/srv/cf/saas-provisioning-service",
196
+ },
197
+ "cds.xt.DeploymentService": {
198
+ model: "@sap/cds-mtxs/srv/deployment-service",
199
+ },
200
+ "cds.xt.DeploymentService-in-sidecar": {
201
+ },
202
+ "cds.xt.DeploymentService-from-sidecar": {
203
+ kind: 'rest'
204
+ },
162
205
 
163
- "uiflex": {
164
- model: "@sap/cds/srv/flex"
206
+ "extensions": {
207
+ model: "@sap/cds/srv/extensions",
208
+ },
209
+ "extensibility": {
210
+ model: [ "@sap/cds/srv/mtx", "@sap/cds/srv/extensions" ]
211
+ },
212
+ "cds.xt.ExtensibilityService": {
213
+ model: "@sap/cds/srv/extensibility-service",
214
+ tenantCheckInterval: 10000
165
215
  },
216
+ "uiflex": "extensibility", // REVISIT: temporary for compatibility with cds-mtxs tests -> eliminate "uiflex" later
166
217
 
167
218
  }
168
219
 
@@ -198,8 +249,7 @@ exports.kinds = {
198
249
  ..._databases,
199
250
  ..._services,
200
251
  ..._messaging,
201
- ..._multitenancy,
202
- ..._extensibility,
252
+ ..._mtx_services,
203
253
  ..._platform_services,
204
254
  }
205
255
 
@@ -0,0 +1,147 @@
1
+ const fs = require('fs')
2
+ const assert = require('assert')
3
+ const path = require('path')
4
+
5
+ const _debug = process.env.DEBUG && process.env.DEBUG.match(/\benv\b/);
6
+ const debug = msg => console.log(msg);
7
+ /* eslint no-console:0 */
8
+
9
+
10
+ const isDirectory = dirPath => fs.statSync(dirPath).isDirectory()
11
+
12
+ function readFiles(dirPath) {
13
+ const result = {}
14
+ for (const dirEntry of fs.readdirSync(dirPath, { withFileTypes: true })) {
15
+ const filePath = path.join(dirPath, dirEntry.name)
16
+ if (isFile(filePath, dirEntry)) {
17
+ result[dirEntry.name] = fs.readFileSync(filePath, 'utf8')
18
+ }
19
+ }
20
+ return result
21
+ }
22
+
23
+ const DEFAULT_META_DATA_PROPERTIES = { type: true, provider: true }
24
+
25
+ function parseJsonSafe(str) {
26
+ try {
27
+ return JSON.parse(str)
28
+ } catch (error) {
29
+ return undefined
30
+ }
31
+ }
32
+
33
+ function buildBindingWithoutMetaData(properties) {
34
+ const binding = { credentials: {} }
35
+
36
+ for (const propertyName in properties) {
37
+ if (propertyName in DEFAULT_META_DATA_PROPERTIES) {
38
+ binding[propertyName] = properties[propertyName]
39
+ } else {
40
+ binding.credentials[propertyName] = properties[propertyName]
41
+ }
42
+ }
43
+
44
+ return binding
45
+ }
46
+
47
+ function parseProperties(properties, metaData = [], bindingPath) {
48
+ const result = {}
49
+
50
+ for (const metaDataProperty of metaData) {
51
+ const { name } = metaDataProperty
52
+ const text = properties[name]
53
+ if (name && typeof text !== 'undefined') {
54
+ let value
55
+ switch (metaDataProperty.format) {
56
+ case 'text':
57
+ result[name] = text
58
+ break
59
+ case 'json':
60
+ value = parseJsonSafe(text)
61
+ if (metaDataProperty.container) {
62
+ Object.assign(result, value)
63
+ } else {
64
+ result[name] = value
65
+ }
66
+ break
67
+ default:
68
+ _debug && debug(`Unexpected format "${metaDataProperty.format}" in service binding "${bindingPath}"`)
69
+ }
70
+ } else {
71
+ _debug && debug(`Missing property "${name}" in service binding "${bindingPath}"`)
72
+ }
73
+ }
74
+
75
+ return result
76
+ }
77
+
78
+ function readBinding(bindingPath, bindingName) {
79
+ const properties = readFiles(bindingPath)
80
+ return parseBinding(bindingPath, bindingName, properties)
81
+ }
82
+
83
+ function parseBinding(bindingPath, bindingName, properties) {
84
+ const metaDataString = properties['.metadata']
85
+ let metaData
86
+ if (metaDataString) {
87
+ metaData = parseJsonSafe(metaDataString)
88
+ if (typeof metaData === 'undefined' && _debug) debug(`Cannot parse JSON: ${bindingPath}/.metadata`)
89
+ }
90
+
91
+ let binding
92
+ if (metaData) {
93
+ binding = parseProperties(properties, metaData.metaDataProperties, bindingPath)
94
+ binding.credentials = parseProperties(properties, metaData.credentialProperties, bindingPath)
95
+ } else {
96
+ binding = buildBindingWithoutMetaData(properties)
97
+ }
98
+
99
+ if (!binding.type) {
100
+ _debug && debug(`Missing type property for service binding "${bindingPath}"`)
101
+ return undefined
102
+ }
103
+
104
+ binding.name = bindingName
105
+ return binding
106
+ }
107
+
108
+ function readServiceBindingsServicesFromPath(serviceBindingRoot) {
109
+ assert(isDirectory(serviceBindingRoot), 'secrets path must be a directory')
110
+
111
+ const bindingsForService = {}
112
+ for (const bindingEntry of fs.readdirSync(serviceBindingRoot, { withFileTypes: true })) {
113
+ if (bindingEntry.isDirectory()) {
114
+ const bindingPath = path.join(serviceBindingRoot, bindingEntry.name)
115
+ const binding = readBinding(bindingPath, bindingEntry.name)
116
+ if (!binding) continue
117
+ const type = binding.type
118
+ const bindings = bindingsForService[type] || (bindingsForService[type] = [])
119
+ bindings.push(binding)
120
+ }
121
+ }
122
+ return Object.keys(bindingsForService).length > 0 ? bindingsForService : undefined
123
+ }
124
+
125
+ function serviceBindings(serviceBindingRoot) {
126
+ serviceBindingRoot = serviceBindingRoot || process.env.SERVICE_BINDING_ROOT
127
+ if ((typeof serviceBindingRoot === 'string' && serviceBindingRoot.length > 0)) {
128
+ return fs.existsSync(serviceBindingRoot) ? readServiceBindingsServicesFromPath(serviceBindingRoot) : undefined
129
+ } else {
130
+ return undefined
131
+ }
132
+ }
133
+
134
+ function isFile(p, entry) {
135
+ if (entry.isFile()) return true
136
+ if (entry.isSymbolicLink()) {
137
+ // Kubernetes credentials use symlinks
138
+ const target = fs.realpathSync(p)
139
+ const targetStat = fs.statSync(target)
140
+
141
+ if (targetStat.isFile()) return true
142
+ }
143
+ return false
144
+ }
145
+
146
+ module.exports = serviceBindings
147
+ module.exports.parseBinding = parseBinding // required by "cds bind"