@sap/cds 5.5.4 → 5.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. package/CHANGELOG.md +138 -1
  2. package/apis/services.d.ts +27 -1
  3. package/app/index.js +22 -11
  4. package/bin/build/buildTaskFactory.js +1 -1
  5. package/bin/build/provider/buildTaskProviderInternal.js +1 -1
  6. package/bin/build/provider/fiori/index.js +1 -1
  7. package/bin/build/provider/hana/2migration.js +8 -7
  8. package/bin/build/provider/java-cf/index.js +1 -1
  9. package/bin/deploy/to-hana/hana.js +1 -17
  10. package/common.cds +8 -0
  11. package/lib/compile/to/sql.js +22 -2
  12. package/lib/connect/bindings.js +2 -1
  13. package/lib/core/reflect.js +4 -1
  14. package/lib/env/index.js +175 -41
  15. package/lib/env/requires.js +16 -1
  16. package/lib/i18n/localize.js +33 -5
  17. package/lib/index.js +3 -3
  18. package/lib/log/format/kibana.js +6 -2
  19. package/lib/ql/Query.js +1 -0
  20. package/lib/ql/SELECT.js +15 -8
  21. package/lib/ql/Whereable.js +5 -0
  22. package/lib/req/context.js +13 -5
  23. package/lib/serve/Service-dispatch.js +8 -1
  24. package/lib/serve/Service-methods.js +1 -1
  25. package/lib/utils/axios.js +7 -0
  26. package/lib/utils/data.js +1 -1
  27. package/lib/utils/tests.js +1 -1
  28. package/libx/_runtime/audit/Service.js +18 -18
  29. package/libx/_runtime/audit/generic/personal/access.js +1 -1
  30. package/libx/_runtime/audit/generic/personal/modification.js +3 -2
  31. package/libx/_runtime/audit/generic/personal/utils.js +23 -63
  32. package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +4 -0
  33. package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +37 -35
  34. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +3 -1
  35. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +5 -5
  36. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +13 -7
  37. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +84 -34
  38. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +10 -4
  39. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/applyToCQN.js +9 -3
  40. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/expandToCQN.js +8 -6
  41. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/index.js +1 -3
  42. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/readToCQN.js +13 -11
  43. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/selectHelper.js +11 -95
  44. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/ResourcePathParser.js +17 -11
  45. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/UriParser.js +2 -1
  46. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/SetResponseHeadersCommand.js +1 -0
  47. package/libx/_runtime/cds-services/adapter/odata-v4/to.js +6 -2
  48. package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +3 -34
  49. package/libx/_runtime/cds-services/adapter/odata-v4/utils/handlerUtils.js +3 -3
  50. package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +64 -31
  51. package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +10 -5
  52. package/libx/_runtime/cds-services/adapter/rest/handlers/operation.js +1 -1
  53. package/libx/_runtime/cds-services/adapter/rest/handlers/update.js +1 -1
  54. package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/index.js +1 -3
  55. package/libx/_runtime/cds-services/adapter/rest/utils/validation-checks.js +20 -21
  56. package/libx/_runtime/cds-services/services/utils/columns.js +6 -1
  57. package/libx/_runtime/cds-services/services/utils/compareJson.js +1 -8
  58. package/libx/_runtime/cds-services/services/utils/differ.js +7 -26
  59. package/libx/_runtime/cds-services/services/utils/handlerUtils.js +2 -4
  60. package/libx/_runtime/cds-services/util/assert.js +29 -13
  61. package/libx/_runtime/cds.js +2 -1
  62. package/libx/_runtime/common/aspects/Association.js +72 -0
  63. package/libx/_runtime/common/aspects/any.js +8 -45
  64. package/libx/_runtime/common/aspects/entity.js +0 -1
  65. package/libx/_runtime/common/aspects/relation.js +40 -0
  66. package/libx/_runtime/common/aspects/utils.js +73 -1
  67. package/libx/_runtime/common/auth/strategies/utils/uaa.js +10 -14
  68. package/libx/_runtime/common/composition/data.js +3 -2
  69. package/libx/_runtime/common/composition/delete.js +3 -1
  70. package/libx/_runtime/common/composition/tree.js +23 -18
  71. package/libx/_runtime/common/composition/update.js +6 -1
  72. package/libx/_runtime/common/composition/utils.js +34 -8
  73. package/libx/_runtime/common/error/frontend.js +6 -1
  74. package/libx/_runtime/common/generic/auth.js +15 -13
  75. package/libx/_runtime/common/generic/crud.js +2 -2
  76. package/libx/_runtime/common/generic/etag.js +11 -8
  77. package/libx/_runtime/common/generic/input.js +3 -3
  78. package/libx/_runtime/common/generic/paging.js +9 -5
  79. package/libx/_runtime/common/generic/put.js +3 -2
  80. package/libx/_runtime/common/generic/sorting.js +3 -3
  81. package/libx/_runtime/common/generic/temporal.js +3 -3
  82. package/libx/_runtime/common/utils/cqn.js +20 -1
  83. package/libx/_runtime/common/utils/cqn2cqn4sql.js +125 -139
  84. package/libx/_runtime/common/utils/csn.js +50 -52
  85. package/libx/_runtime/common/utils/foreignKeyPropagations.js +41 -176
  86. package/libx/_runtime/common/utils/generateOnCond.js +40 -70
  87. package/libx/_runtime/common/utils/{enrichWithKeysFromWhere.js → keys.js} +29 -28
  88. package/libx/_runtime/common/utils/postProcessing.js +3 -0
  89. package/libx/_runtime/common/utils/propagateForeignKeys.js +84 -0
  90. package/libx/_runtime/common/utils/resolveStructured.js +1 -1
  91. package/libx/_runtime/common/utils/resolveView.js +7 -5
  92. package/libx/_runtime/common/utils/rewriteAsterisks.js +94 -0
  93. package/libx/_runtime/common/utils/search2cqn4sql.js +9 -8
  94. package/libx/_runtime/common/utils/template.js +54 -46
  95. package/libx/_runtime/db/Service.js +9 -2
  96. package/libx/_runtime/db/expand/expandCQNToJoin.js +54 -33
  97. package/libx/_runtime/db/expand/rawToExpanded.js +2 -1
  98. package/libx/_runtime/db/generic/arrayed.js +13 -28
  99. package/libx/_runtime/db/generic/create.js +1 -0
  100. package/libx/_runtime/db/generic/input.js +7 -11
  101. package/libx/_runtime/db/generic/integrity.js +2 -2
  102. package/libx/_runtime/db/generic/rewrite.js +2 -5
  103. package/libx/_runtime/db/generic/update.js +1 -0
  104. package/libx/_runtime/db/query/read.js +9 -4
  105. package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +6 -0
  106. package/libx/_runtime/db/sql-builder/SelectBuilder.js +7 -2
  107. package/libx/_runtime/db/sql-builder/annotations.js +1 -0
  108. package/libx/_runtime/db/utils/columns.js +14 -43
  109. package/libx/_runtime/db/utils/deep.js +5 -7
  110. package/libx/_runtime/fiori/generic/activate.js +3 -2
  111. package/libx/_runtime/fiori/generic/before.js +2 -2
  112. package/libx/_runtime/fiori/generic/cancel.js +3 -2
  113. package/libx/_runtime/fiori/generic/delete.js +3 -2
  114. package/libx/_runtime/fiori/generic/edit.js +3 -3
  115. package/libx/_runtime/fiori/generic/new.js +2 -2
  116. package/libx/_runtime/fiori/generic/patch.js +2 -2
  117. package/libx/_runtime/fiori/generic/prepare.js +2 -2
  118. package/libx/_runtime/fiori/generic/read.js +17 -63
  119. package/libx/_runtime/fiori/generic/readOverDraft.js +4 -4
  120. package/libx/_runtime/fiori/uiflex/extensibility/index.cds +15 -0
  121. package/libx/_runtime/fiori/uiflex/extensibility/index.js +148 -0
  122. package/libx/_runtime/fiori/uiflex/handler/transformREAD.js +119 -0
  123. package/libx/_runtime/fiori/uiflex/handler/transformRESULT.js +43 -0
  124. package/libx/_runtime/fiori/uiflex/handler/transformWRITE.js +62 -0
  125. package/libx/_runtime/fiori/uiflex/index.js +35 -0
  126. package/libx/_runtime/fiori/uiflex/utils.js +78 -0
  127. package/libx/_runtime/fiori/utils/handler.js +3 -13
  128. package/libx/_runtime/fiori/utils/where.js +6 -1
  129. package/libx/_runtime/hana/pool.js +12 -11
  130. package/libx/_runtime/hana/search2cqn4sql.js +34 -43
  131. package/libx/_runtime/hana/searchToContains.js +3 -3
  132. package/libx/_runtime/index.js +5 -2
  133. package/libx/_runtime/messaging/AMQPWebhookMessaging.js +1 -1
  134. package/libx/_runtime/messaging/common-utils/AMQPClient.js +16 -3
  135. package/libx/_runtime/messaging/common-utils/connections.js +11 -14
  136. package/libx/_runtime/messaging/common-utils/naming-conventions.js +1 -1
  137. package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +2 -1
  138. package/libx/_runtime/messaging/message-queuing.js +18 -0
  139. package/libx/_runtime/remote/Service.js +20 -4
  140. package/libx/_runtime/remote/utils/client-types.d.ts +7 -0
  141. package/libx/_runtime/remote/utils/client.js +117 -23
  142. package/libx/_runtime/sqlite/Service.js +2 -2
  143. package/libx/_runtime/sqlite/convertAssocToOneManaged.js +1 -3
  144. package/libx/gql/GraphQLAdapter.js +33 -0
  145. package/libx/gql/constants/adapter.js +69 -0
  146. package/libx/gql/constants/cds.js +18 -0
  147. package/libx/gql/constants/graphql.js +33 -0
  148. package/libx/gql/resolvers/crud/create.js +15 -0
  149. package/libx/gql/resolvers/crud/delete.js +24 -0
  150. package/libx/gql/resolvers/crud/index.js +6 -0
  151. package/libx/gql/resolvers/crud/read.js +25 -0
  152. package/libx/gql/resolvers/crud/update.js +31 -0
  153. package/libx/gql/resolvers/crud/utils/index.js +36 -0
  154. package/libx/gql/resolvers/field.js +5 -0
  155. package/libx/gql/resolvers/index.js +7 -0
  156. package/libx/gql/resolvers/mutation.js +23 -0
  157. package/libx/gql/resolvers/parse/ast/enrich.js +51 -0
  158. package/libx/gql/resolvers/parse/ast/fragment.js +11 -0
  159. package/libx/gql/resolvers/parse/ast/fromObject.js +39 -0
  160. package/libx/gql/resolvers/parse/ast/index.js +3 -0
  161. package/libx/gql/resolvers/parse/ast/meta.js +4 -0
  162. package/libx/gql/resolvers/parse/ast/variable.js +7 -0
  163. package/libx/gql/resolvers/parse/ast2cqn/columns.js +42 -0
  164. package/libx/gql/resolvers/parse/ast2cqn/entries.js +31 -0
  165. package/libx/gql/resolvers/parse/ast2cqn/index.js +8 -0
  166. package/libx/gql/resolvers/parse/ast2cqn/limit.js +6 -0
  167. package/libx/gql/resolvers/parse/ast2cqn/orderBy.js +24 -0
  168. package/libx/gql/resolvers/parse/ast2cqn/utils/index.js +3 -0
  169. package/libx/gql/resolvers/parse/ast2cqn/where.js +70 -0
  170. package/libx/gql/resolvers/parse/utils/index.js +8 -0
  171. package/libx/gql/resolvers/query.js +13 -0
  172. package/libx/gql/resolvers/root.js +34 -0
  173. package/libx/gql/schema/generate.js +18 -0
  174. package/libx/gql/schema/index.js +5 -0
  175. package/libx/gql/schema/mutation.js +76 -0
  176. package/libx/gql/schema/query.js +108 -0
  177. package/libx/gql/schema/typeDefMap.js +45 -0
  178. package/libx/gql/schema/utils/index.js +54 -0
  179. package/libx/gql/utils/index.js +12 -0
  180. package/libx/{_runtime/odata/cqn2odata.js → odata/cqn2odata/index.js} +39 -100
  181. package/libx/odata/index.js +80 -0
  182. package/libx/odata/odata2cqn/afterburner.js +170 -0
  183. package/libx/{_runtime/odata/odata2cqn.pegjs → odata/odata2cqn/grammar.pegjs} +102 -123
  184. package/libx/odata/odata2cqn/index.js +3 -0
  185. package/libx/odata/odata2cqn/parser.js +1 -0
  186. package/libx/odata/utils/index.js +64 -0
  187. package/libx/rest/RestAdapter.js +101 -0
  188. package/libx/rest/RestRequest.js +30 -0
  189. package/libx/rest/index.js +3 -0
  190. package/libx/rest/middleware/auth.js +22 -0
  191. package/libx/rest/middleware/content.js +15 -0
  192. package/libx/rest/middleware/create.js +40 -0
  193. package/libx/rest/middleware/delete.js +20 -0
  194. package/libx/rest/middleware/error.js +56 -0
  195. package/libx/rest/middleware/operation.js +39 -0
  196. package/libx/rest/middleware/parse.js +90 -0
  197. package/libx/rest/middleware/read.js +29 -0
  198. package/libx/rest/middleware/update.js +42 -0
  199. package/libx/rest/utils/data.js +65 -0
  200. package/package.json +4 -1
  201. package/server.js +29 -7
  202. package/libx/_runtime/cds-services/services/utils/diff.js +0 -53
  203. package/libx/_runtime/cds-services/util/auditlog.js +0 -247
  204. package/libx/_runtime/cds-services/util/xsenv.js +0 -51
  205. package/libx/_runtime/common/utils/backlinks.js +0 -83
  206. package/libx/_runtime/common/utils/rewriteAsterisk.js +0 -72
  207. package/libx/_runtime/odata/index.js +0 -55
  208. package/libx/_runtime/odata/odata2cqn.js +0 -1
  209. package/libx/_runtime/odata/readToCqn.js +0 -129
  210. package/libx/_runtime/remote/cqn2odata/index.js +0 -2
package/CHANGELOG.md CHANGED
@@ -4,6 +4,142 @@
4
4
  - The format is based on [Keep a Changelog](http://keepachangelog.com/).
5
5
  - This project adheres to [Semantic Versioning](http://semver.org/).
6
6
 
7
+ ## Version 5.6.2 - 2021-11-08
8
+
9
+ ### Fixed
10
+
11
+ - Handle arrayed elements using templating mechanism
12
+ - OData requests to `$count` endpoint of ETag enabled entity
13
+ - `cds.test` does no longer crash if executed in `cds repl` on a remote service call
14
+ - Crash on draft activate after draft edit for not existing composition of one
15
+ - Ensure request correlation (with default server)
16
+ - `<entity>.texts` points to real text entity
17
+ - Draft union with expand to to-one and to-many
18
+ - No columns in draft lock statement (i.e., use `SELECT 1`)
19
+
20
+ ## Version 5.6.1 - 2021-11-02
21
+
22
+ ### Fixed
23
+
24
+ - UAA credentials lookup
25
+ - Revert return type validation for `cds.String` for compatibility with older `@sap/cds-mtx` versions
26
+ - Messaging: Ill-defined incoming AMQP messages will not crash the app
27
+ - `cds compile -l` does no longer crash if called without `--to` option
28
+
29
+ ## Version 5.6.0 - 2021-10-29
30
+
31
+ ### Added
32
+
33
+ - New REST protocol adapter (beta)
34
+ + Makes use of the beta OData URL to CQN parser. Hence, almost all OData requests are supported (see limitations below).
35
+ + Activate via `cds.env.features.rest_new_adapter = true`
36
+ + Out of scope (compared to OData protocol adapter):
37
+ + OData query option `$apply`
38
+ + Batch requests (with or without atomicity groups)
39
+ + Draft handling
40
+ - New GraphQL protocol adapter (alpha)
41
+ + Serves single endpoint for all services based on `served` event at `/graphql` (subject to change).
42
+ + Activate via `cds.env.features.graphql = true`
43
+ + Required additional dependencies: `@graphql-tools/schema`, `express-graphql`, and `graphql`
44
+ + Not meant for productive use! For example, authentication and authorization are out of scope.
45
+ - Support of the following features when using beta OData URL to CQN parser (`cds.env.features.odata_new_parser`):
46
+ + REST-style URLs (example: `GET /Foo/1`)
47
+ + `$expand=*` query option on different nested expand levels (`$levels` is not yet supported)
48
+ + draft handling
49
+ + structured keys
50
+ + streaming
51
+ + navigation to primitive properties without `$value` query option
52
+ - Optimized Search: Support `$filter` query option in combination with optimize `$search` and localized data (when the environment variable `cds.env.features.optimized_search` is set to `true`)
53
+ - `GET` requests support static values in ON-conditions of composition parents when using unmanaged backlinks
54
+ - `destinationOptions` can be configured for Remote Services
55
+ + Example:
56
+ ```json
57
+ {"cds":{"requires":{
58
+ "S4": {
59
+ "destinationOptions": {
60
+ "selectionStrategy": "subscriberFirst",
61
+ ...
62
+ }
63
+ }
64
+ }}}
65
+ ```
66
+ - `forwardAuthToken` can be configured for Remote Services
67
+ + Example:
68
+ ```json
69
+ {"cds":{"requires":{
70
+ "credentials": {
71
+ "url": "...",
72
+ "forwardAuthToken": true
73
+ }
74
+ }
75
+ }}}
76
+ ```
77
+ - File to store private project settings `.cdsrc-private.json` (should not be checked in source code management)
78
+ - Read additional configuration from JSON files or directory structures using `CDS_CONFIG` env variable
79
+ - Missing typescript definitions for services' `.send` shortcuts `get`, `put`, `post`, `patch`, and `delete`
80
+ - Build VCAP_SERVICES env variable dynamically for compatibility (`cds.env.features.emulate_vcap_services`)
81
+ - GET requests to Remote OData Service are automatically sent as `$batch` if the generated URL is too long
82
+ + Can be configured via `cds.env.remote.max_get_url_length` (beta, default: 1028).
83
+ - Provide ETag in response headers in case of `prefer: return=minimal`
84
+ - Kibana formatter: log the user's id via `cds.env.log.user = true` (beta)
85
+ + Consider the data privacy implications!
86
+ - Experimental support for uiflex running locally on sqlite by setting `cds.requires.extensibility.kind = uiflex`
87
+ - Minified `cds.model` (deactivate via `cds.env.features.skip_unused = false`)
88
+
89
+ ### Changed
90
+
91
+ - Query API: Specified keys are now part of the target path, e.g. `SELECT.from('Books', 1)` will move the key condition into `SELECT.from.ref`.
92
+ + Deactivate during two month grace period via compat feature flag `cds.env.features.keys_into_where = true`
93
+ - Removed duplicate integrity checks
94
+ - Optimized search: Optimize queries for non-localized elements
95
+ - Non-specified columns are resolved at database layer
96
+ - `cds deploy` no longer enforces the presence of SAP CommonCryptoLib (checked with env variable `SECUDIR`) on Windows since it uses now the built-in security libraries
97
+ - Target keys are not included into a body when sending `PATCH` requests to external services
98
+
99
+ ### Fixed
100
+
101
+ - Audit logging of non-string values
102
+ - Query API compilation error when keys start with `{`
103
+ - Handling of wrong Edm.DateTimeOffset values
104
+ - Using UUIDs in search with beta OData URL to CQN parser (`cds.env.features.odata_new_parser`)
105
+ - Runtime exception for READ requests with deeply nested navigation and structured keys, for example:
106
+ `GET foo/Bar/b708ad6c-2dd4-40d5-91c0-2e3eacf306d2/Info/sales(a='1010',b='10',c='00')/functions(functionName='error')`
107
+ - The check for the minimum Node.js version now properly enforces version 12.18, i.e. aborts server startup.
108
+ - `cds.test` fails with a clearer error message if the server wasn't started at all
109
+ - Audit logging for modification of personal or sensitive data when using same entity as a composition child in different parent entities
110
+ - Deleting an entity defined with managed composition of one, whereas a dependent entity is defined having an independent managed association to its composition parent no longer crashes the application
111
+ - Audit logging for entities having arrayed elements
112
+ - Filtering for `cds.Date` on Remote OData V2 services
113
+ - Crash when `rollup` function was used in groupBy in odata requests
114
+ - Or for $filter with IsActiveEntity=true for access to active entities
115
+ - Reading draft-enabled entity with `$expand` targeting non-draft associations
116
+ - Delete with sub-select
117
+ - Runtime exception when streaming property annotated with `@Core.MediaType: 'application/json'`
118
+ - Reading streams via navigation when entity containing large data is a part of a draft-enabled composition tree
119
+ - Read draft entity with nested exists restriction
120
+ - Activate draft of entity having `to-one` and `to-many` compositions
121
+ - Caching issue that causes the OData `omit-values` preference in `Prefer` HTTP headers to misbehaves
122
+ - Deletion of draft instances if multiple draft enabled entities are used within one service
123
+ - Queries with `contains` filter targeting a remote odata v2 service
124
+ - Schema evolution support for nested CDS entities in `cds build`
125
+ - I18n texts with quotes and other special characters get escaped correctly if they appear in XML and Json documents
126
+ - Execution of plain SQL statements on SQLite
127
+ - `Content-Disposition` header is now url encoded
128
+
129
+ ### Removed
130
+
131
+ - Usage of `@sap/xsenv` is superseded with `cds.env` in node.js cds-runtime
132
+ - `@odata.on.insert/update` and `#user/now` are deprecated and will be removed in the next major version. Use `@cds.on.insert/update` and `$user/now` instead.
133
+
134
+ ## Version 5.5.5 - 2021-10-20
135
+
136
+ ### Fixed
137
+
138
+ - Action parameters set to null
139
+ - Restrictions with "where exists" clause and filter on ambiguous fields
140
+ - Nulled user attribute in restrictions with "where exists" clause
141
+ - Wait for all queries to settle during deep operation
142
+
7
143
  ## Version 5.5.4 - 2021-10-12
8
144
 
9
145
  ### Fixed
@@ -49,6 +185,7 @@
49
185
  ### Added
50
186
 
51
187
  - Support for minified models
188
+ - Messaging: Support for string payloads
52
189
  - Messaging: Webhooks use 'application/json' as the default content type
53
190
  - Messaging: If senders don't use `data` as a property of the payload, then the whole payload is interpreted as `data`
54
191
  - Messaging: Support for `$namespace` placeholer in queue name
@@ -146,7 +283,7 @@
146
283
  - Messaging: In multitenancy mode, messaging artifacts are only deployed to subscribers (unless the service option `deployForProvider` is set to `true`)
147
284
  - Messaging: Incoming messages without corresponding handlers are not acknowledged
148
285
  - If a service executes a query targeting a projection on one of its entities, the query is resolved along with projections to an entity known by the executing service. The result is post-processed to reflect the expected result of the incoming query. The reason is that no handlers of the executing service were executed as they did not know the query target.
149
- + Deactivate during two month grace period via compact feature flag `cds.env.features.resolve_views = false`
286
+ + Deactivate during two month grace period via compat feature flag `cds.env.features.resolve_views = false`
150
287
  - Use `@sap/cds-compiler`'s `smartId` function to determine whether a reference needs to be quoted.
151
288
  + Allows the use of non-word characters in column names, for example `entity Foo { ![bar/bz]: String; }`.
152
289
  + Support for columns with spaces with feature flag `cds.env.features.spaced_columns`.
@@ -140,7 +140,33 @@ export class Service extends QueryAPI {
140
140
  */
141
141
  send (details: { event: Events, data?: object, headers?: object }) : Promise<this>
142
142
 
143
- // The central method to dispatch events
143
+ /**
144
+ * Constructs and sends a GET request.
145
+ * @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-send)
146
+ */
147
+ get (entityOrPath: Target, data?: object) : Promise<this>
148
+ /**
149
+ * Constructs and sends a POST request.
150
+ * @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-send)
151
+ */
152
+ post (entityOrPath: Target, data?: object) : Promise<this>
153
+ /**
154
+ * Constructs and sends a PUT request.
155
+ * @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-send)
156
+ */
157
+ put (entityOrPath: Target, data?: object) : Promise<this>
158
+ /**
159
+ * Constructs and sends a PATCH request.
160
+ * @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-send)
161
+ */
162
+ patch (entityOrPath: Target, data?: object) : Promise<this>
163
+ /**
164
+ * Constructs and sends a DELETE request.
165
+ * @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-send)
166
+ */
167
+ delete (entityOrPath: Target, data?: object) : Promise<this>
168
+
169
+ // The central method to dispatch events
144
170
  dispatch (msg: EventMessage): Promise<any>
145
171
 
146
172
 
package/app/index.js CHANGED
@@ -6,7 +6,7 @@ module.exports = { get html(){
6
6
  const odata = srv => Object.keys(srv._adapters).find (a => a.startsWith ('odata'))
7
7
  const metadata = srv => odata(srv) ? ` / <a href="${srv.path}/$metadata">$metadata</a>` : ``
8
8
 
9
- const html = fs.readFileSync(path.join(__dirname,'index.html'),'utf-8')
9
+ let html = fs.readFileSync(path.join(__dirname,'index.html'),'utf-8')
10
10
  // .replace ('{{subtitle}}', 'Version ' + cds.version)
11
11
  .replace (/{{package}}/g, _project())
12
12
  .replace (/{{app}}/g, cds.env.folders.app.replace(/*trailing slash*/ /\/$/, ''))
@@ -15,16 +15,27 @@ module.exports = { get html(){
15
15
  ).join('\n') || '— none —'
16
16
  )
17
17
  .replace ('{{services}}', cds.service.providers.map (srv => `
18
- <h3>
19
- <a href="${srv.path}">${srv.path}</a>${metadata(srv)} ${_moreLinks(srv)}
20
- </h3>
21
- <ul>${_entities_in(srv).map (e => {
22
- return `
23
- <li>
24
- <a href="${srv.path}/${e.replace(/\./g, '_')}">${e}</a> ${_moreLinks(srv, e)}
25
- </li>`}).join('')}
26
- </ul>
27
- `) .join(''))
18
+ <h3>
19
+ <a href="${srv.path}">${srv.path}</a>${metadata(srv)} ${_moreLinks(srv)}
20
+ </h3>
21
+ <ul>${_entities_in(srv).map (e => {
22
+ return `
23
+ <li>
24
+ <a href="${srv.path}/${e.replace(/\./g, '_')}">${e}</a> ${_moreLinks(srv, e)}
25
+ </li>`}).join('')}
26
+ </ul>
27
+ `).join(''))
28
+
29
+ // add /graphql
30
+ if (cds.env.features.graphql) {
31
+ html = html.replace(/\n\s*<footer>/, `
32
+
33
+ <h3>
34
+ <a href="/graphql">/graphql</a>
35
+ </h3>
36
+
37
+ <footer>`)
38
+ }
28
39
 
29
40
  Object.defineProperty (this,'html',{value:html})
30
41
  return html
@@ -150,7 +150,7 @@ class BuildTaskFactory {
150
150
  _adaptBuildTargetSettingForJava(projectPath) {
151
151
  if (this.env.build.target !== ".") {
152
152
  // filter user settings of cds.env
153
- const userEnv = this.env.for("cds", projectPath, false, true)
153
+ const userEnv = this.env.for("cds", projectPath, false)
154
154
 
155
155
  // use helper as env.build might be undefined
156
156
  if (!getProperty(userEnv, "build.target")) {
@@ -174,7 +174,7 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
174
174
  }
175
175
  // check whether cds config represents a legacy build system config for which requires.db was not configured
176
176
  // Note: compat layer sets requires.db: {}
177
- const userEnv = this.cds.env.for("cds", projectPath, false, true)
177
+ const userEnv = this.cds.env.for("cds", projectPath, false)
178
178
  return userEnv && (userEnv.get("data.model") || userEnv.get("service.model"))
179
179
  }
180
180
 
@@ -51,7 +51,7 @@ class FioriAppModuleBuilder extends BuildTaskHandlerEdmx {
51
51
 
52
52
  if (javaTask
53
53
  && await isOldJavaStack([javaTask.src, this.buildOptions.root])
54
- && !this.env.for("cds", this.buildOptions.root, false, true).get(ODATA_VERSION)) {
54
+ && !this.env.for("cds", this.buildOptions.root, false).get(ODATA_VERSION)) {
55
55
 
56
56
  // old java stack
57
57
  // default is now v4 and not v2 anymore, so overwrite with v2 if using default
@@ -1,6 +1,7 @@
1
1
  const path = require('path')
2
2
  const parser = require('./migrationtable')
3
3
  const { getProperty, BuildError } = require('../../util')
4
+ const { getArtifactCdsPersistenceName } = require('@sap/cds-compiler')
4
5
  const { LOG_MODULE_NAMES } = require('../../constants')
5
6
  const cdscVersion = `-- generated by cds-compiler version ${require('@sap/cds-compiler/package.json').version}`
6
7
  const cds = require('../../cds'), minified = csn => cds.linked(csn).minified()
@@ -12,15 +13,15 @@ module.exports = async (model, lastDevVersion, srcPath, options = {}) => {
12
13
  logger = options.logger
13
14
  }
14
15
 
15
- const journalEntityNames = _getJournalEntityNames(model)
16
- const { definitions, deletions, migrations, afterImage } = _toHdiMigration(model, lastDevVersion, journalEntityNames, options)
16
+ const journalFileNames = _getJournalFileNames(model)
17
+ const { definitions, deletions, migrations, afterImage } = _toHdiMigration(model, lastDevVersion, journalFileNames, options)
17
18
  const definitionResult = []
18
19
 
19
20
  for (const { name, suffix, sql } of definitions) {
20
21
  let definitionEntry = { name, suffix, content: sql }
21
22
 
22
23
  if (suffix === '.hdbtable') {
23
- if (journalEntityNames.has(name)) {
24
+ if (journalFileNames.has(name)) {
24
25
  const migration = migrations.find(migration => migration.name === name)
25
26
  definitionEntry = await _2migrationtable(srcPath, migration || _emptyMigration(name), sql, options)
26
27
  }
@@ -32,14 +33,14 @@ module.exports = async (model, lastDevVersion, srcPath, options = {}) => {
32
33
  return { definitions: definitionResult, deletions, afterImage }
33
34
  }
34
35
 
35
- function _toHdiMigration(model, lastDevVersion, journalEntityNames, options) {
36
+ function _toHdiMigration(model, lastDevVersion, journalFileNames, options) {
36
37
  options.sqlChangeMode = getProperty(options, 'hana.journal.change-mode')
37
38
  const result = cdsc.to.hdi.migration(minified(model), options, lastDevVersion);
38
39
  if (logger._debug) {
39
40
  logger.debug('cdsc.to.hdi.migration returned')
40
41
  for (const { name, suffix, sql } of result.definitions) {
41
42
  if (suffix === '.hdbtable' || suffix === '.hdbmigrationtable') {
42
- if (journalEntityNames.has(name)) {
43
+ if (journalFileNames.has(name)) {
43
44
  const migration = result.migrations.find(migration => migration.name === name)
44
45
  logger.debug(`
45
46
  File ${name + '.hdbmigrationtable'} - ${migration ? migration.changeset.length : 0} new changes
@@ -132,7 +133,7 @@ function _emptyMigration(name) {
132
133
  return { name, suffix: ".hdbmigrationtable", changeset: [] }
133
134
  }
134
135
 
135
- function _getJournalEntityNames(model) {
136
+ function _getJournalFileNames(model) {
136
137
  const journalNames = new Set(cds.reflect(model).all(item => {
137
138
  if (item.kind === 'entity' && item['@cds.persistence.journal'] === true) {
138
139
  if (item['@cds.persistence.skip'] === true || item['@cds.persistence.exists'] === true) {
@@ -141,7 +142,7 @@ function _getJournalEntityNames(model) {
141
142
  return true
142
143
  }
143
144
  return false
144
- }).map(entity => entity.name))
145
+ }).map(entity => getArtifactCdsPersistenceName(entity.name, 'quoted', model)))
145
146
 
146
147
  logger._debug && logger.debug(`\n[hdbmigrationtable] found ${journalNames.size} model entities annotated with '@cds.persistence.journal`)
147
148
  logger._debug && logger.debug(`[hdbmigrationtable] ${[...journalNames].join(', ')}\n`)
@@ -27,7 +27,7 @@ class JavaCfModuleBuilder extends BuildTaskHandlerEdmx {
27
27
  throw new BuildError('CDS compiler version 2 does no longer support the classic CAP Java runtime. It is recommended to migrate to the current CAP Java runtime SDK. See https://cap.cloud.sap/docs/java/migration for more.')
28
28
  }
29
29
  // default is now v4 and not v2 anymore, so warn and overwrite with v2 if using default
30
- if (!this.env.for('cds', this.buildOptions.root, false, true).get(ODATA_VERSION)) {
30
+ if (!this.env.for('cds', this.buildOptions.root, false).get(ODATA_VERSION)) {
31
31
  odataOptions.version = ODATA_VERSION_V2
32
32
  this.pushMessage('Forcing OData v2 for building though the default is v4. Make sure to define OData v2 in cds configuration.', INFO)
33
33
  }
@@ -11,7 +11,7 @@ const { defaultLogger, nullLogger } = require('./logger');
11
11
  const hdiDeployUtil = require('./hdiDeployUtil');
12
12
  const mtaUtil = require('../../build/mtaUtil');
13
13
  const runCommand = require('./runCommand');
14
- const { bold, error, info } = require('../../utils/term');
14
+ const { bold, info } = require('../../utils/term');
15
15
 
16
16
 
17
17
  const IS_WIN = (os.platform() === 'win32');
@@ -27,8 +27,6 @@ class HanaDeployer {
27
27
  logger.log(`[cds.deploy] - ${bold('Starting deploy to SAP HANA ...')}`);
28
28
  logger.log();
29
29
 
30
- this._validateEnvironment(logger);
31
-
32
30
  const projectPath = path.resolve(process.env._TEST_CWD || process.cwd());
33
31
 
34
32
  const { buildResults } = await this._build(buildTaskOptions, model, logger);
@@ -276,20 +274,6 @@ ${entry}
276
274
  }
277
275
  }
278
276
 
279
-
280
- _validateEnvironment(logger) {
281
- if (IS_WIN && !process.env.SECUDIR) {
282
- const helpUrl = info('https://help.sap.com/viewer/e54136ab6a4a43e6a370265bf0a2d744/latest/en-US/c049e28431ee4e8280cd6f5d1a8937d8.html');
283
- const errMessage = error('[ERROR]') + ` [cds.deploy] - In order to use the hdi deployer on ${bold("Windows")} you require the ${bold("SAP CommonCryptoLib")}.
284
- Please follow ${helpUrl}
285
- for further information on how to obtain ${bold("SAP CommonCryptoLib")}.
286
- `;
287
- logger.error(errMessage);
288
- throw new Error(`[cds.deploy] - Missing SAP CommonCryptoLib`);
289
- }
290
- }
291
-
292
-
293
277
  _getVCAPServicesEntry(serviceInstanceName, serviceKey) {
294
278
  return {
295
279
  hana: [
package/common.cds CHANGED
@@ -65,6 +65,13 @@ aspect temporal {
65
65
  type User : String(255);
66
66
 
67
67
 
68
+ /*
69
+ * Aspects for extensible entities.
70
+ */
71
+ aspect extensible {
72
+ @cds.api.ignore extensions__ : String
73
+ };
74
+
68
75
  //---------------------------------------------------------------------------
69
76
  // Annotations for Fiori UIs...
70
77
 
@@ -122,6 +129,7 @@ annotate managed with {
122
129
  //---------------------------------------------------------------------------
123
130
  // Temporary Workarounds...
124
131
 
132
+ // REVISIT: Remove support for @odata.on... and #... with @sap/cds ^6
125
133
  // REVISIT: change @odata.on... to @cds.on...
126
134
  // REVISIT: @cds.on... should automatically result in @readonly @Core.Computed
127
135
 
@@ -1,9 +1,9 @@
1
1
  const cds = require ('../..'), minified = csn => cds.linked(csn).minified()
2
2
  const cdsc = require ('../cdsc')
3
3
  const {unfold_ddl} = cds.alpha_localized
4
+ const EXT_BACK_PACK = 'extensions__'
4
5
 
5
-
6
- function cds_compile_to_sql (csn,_o) {
6
+ function cds_compile_to_sql_ (csn,_o) {
7
7
  const o = cdsc._options.for.sql(_o) //> used twice below...
8
8
  const all = cdsc.to.sql (minified(csn),o)
9
9
  const sql = unfold_ddl (all.map (each => each
@@ -13,6 +13,26 @@ function cds_compile_to_sql (csn,_o) {
13
13
  return sql
14
14
  }
15
15
 
16
+ function cds_compile_to_sql (csn,_o) {
17
+ const defs = cds.linked(csn).definitions
18
+ for (let each in defs) {
19
+ const d = defs[each], q = d.query
20
+ // q may have SET instead of SELECT
21
+ if (q && q.SELECT && q.SELECT.columns && _is_extensible(d)) _add_extensions2 (q.SELECT.columns)
22
+ }
23
+ function _is_extensible (d) {
24
+ if(!d || !d.elements) return false
25
+ if (EXT_BACK_PACK in d.elements) return true
26
+ else return _is_extensible (d.__proto__)
27
+ }
28
+ function _add_extensions2 (cols) {
29
+ if (cols.some(({ref}) => ref && ref[0] === EXT_BACK_PACK)) return
30
+ cols.push({ref:[EXT_BACK_PACK]})
31
+ }
32
+ const ddl = cds_compile_to_sql_ (csn,_o)
33
+ return ddl
34
+ }
35
+
16
36
 
17
37
  function cds_compile_to_hdbtable (csn,o) {
18
38
  const all = cdsc.to.hdi (minified(csn),o)
@@ -19,9 +19,10 @@ module.exports = class Bindings {
19
19
  return bindings.import() .then (r,e)
20
20
  }
21
21
 
22
- constructor() {
22
+ constructor(url) {
23
23
  this._source = require ('path') .resolve (cds.root, registry.replace(/^~/, require('os').homedir()))
24
24
  this.cds = {provides:{}}
25
+ this.url = url
25
26
  }
26
27
 
27
28
  async load (sync) {
@@ -1,5 +1,6 @@
1
1
  const { types, classes:{ service, entity, action, event, any, struct, array, context, annotation } } = require('.')
2
2
  const _kinds = { annotation, context, service, action, event, entity, view:entity }
3
+ const _minified = Symbol('minified')
3
4
 
4
5
  class LinkedCSN extends any {
5
6
 
@@ -25,6 +26,7 @@ class LinkedCSN extends any {
25
26
  /* else: */ any.prototype
26
27
  )
27
28
  if (p.key && !d.key && d.kind === 'element') Object.defineProperty (d,'key',{value:undefined}) //> don't propagate .key
29
+ if (d.elements && d.elements.localized) Object.defineProperty (d,'texts',{value: defs [d.elements.localized.target] })
28
30
  try { return Object.setPrototypeOf(d,p) } //> link d to resolved proto
29
31
  catch(e) { //> cyclic proto error
30
32
  let msg = d.name; for (; p && p.name; p = p.__proto__) msg += ' > '+p.name
@@ -48,6 +50,7 @@ class LinkedCSN extends any {
48
50
 
49
51
  minified (skip = global.cds.env.features.skip_unused) {
50
52
  if (!skip) return this
53
+ if (this[_minified]) return this; else _set (this,_minified,true)
51
54
  const csn = this, all = csn.definitions, reached = new Set
52
55
  const roots = skip === 'all' ? this.services : this.each(_root)
53
56
  for (let each of roots) _visit (each)
@@ -74,7 +77,7 @@ class LinkedCSN extends any {
74
77
  if (n.endsWith('.texts')) delete all[n.replace('.texts','_texts')]
75
78
  }
76
79
  }
77
- return csn
80
+ return this
78
81
  }
79
82
 
80
83
  *each (x, defs=this.definitions) {