@sap/cds 5.5.5 → 5.6.3

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 (207) hide show
  1. package/CHANGELOG.md +139 -1
  2. package/apis/services.d.ts +31 -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 +180 -42
  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/utils/axios.js +7 -0
  25. package/lib/utils/data.js +1 -1
  26. package/lib/utils/tests.js +1 -1
  27. package/libx/_runtime/audit/Service.js +18 -18
  28. package/libx/_runtime/audit/generic/personal/access.js +1 -1
  29. package/libx/_runtime/audit/generic/personal/modification.js +3 -2
  30. package/libx/_runtime/audit/generic/personal/utils.js +23 -63
  31. package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +4 -0
  32. package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +37 -35
  33. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +3 -1
  34. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +5 -5
  35. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +13 -7
  36. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +84 -34
  37. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +12 -4
  38. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/applyToCQN.js +9 -3
  39. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/expandToCQN.js +8 -6
  40. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/index.js +1 -3
  41. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/readToCQN.js +13 -11
  42. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/selectHelper.js +11 -95
  43. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/ResourcePathParser.js +17 -11
  44. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/UriParser.js +2 -1
  45. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/SetResponseHeadersCommand.js +1 -0
  46. package/libx/_runtime/cds-services/adapter/odata-v4/to.js +6 -2
  47. package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +3 -34
  48. package/libx/_runtime/cds-services/adapter/odata-v4/utils/handlerUtils.js +3 -3
  49. package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +64 -31
  50. package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +10 -5
  51. package/libx/_runtime/cds-services/adapter/rest/handlers/operation.js +1 -1
  52. package/libx/_runtime/cds-services/adapter/rest/handlers/update.js +1 -1
  53. package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/index.js +1 -3
  54. package/libx/_runtime/cds-services/adapter/rest/utils/validation-checks.js +20 -21
  55. package/libx/_runtime/cds-services/services/utils/columns.js +6 -1
  56. package/libx/_runtime/cds-services/services/utils/compareJson.js +1 -8
  57. package/libx/_runtime/cds-services/services/utils/differ.js +7 -26
  58. package/libx/_runtime/cds-services/services/utils/handlerUtils.js +2 -4
  59. package/libx/_runtime/cds-services/util/assert.js +29 -13
  60. package/libx/_runtime/cds.js +2 -1
  61. package/libx/_runtime/common/aspects/Association.js +72 -0
  62. package/libx/_runtime/common/aspects/any.js +8 -45
  63. package/libx/_runtime/common/aspects/entity.js +0 -1
  64. package/libx/_runtime/common/aspects/relation.js +40 -0
  65. package/libx/_runtime/common/aspects/utils.js +73 -1
  66. package/libx/_runtime/common/auth/strategies/utils/uaa.js +10 -14
  67. package/libx/_runtime/common/composition/data.js +3 -2
  68. package/libx/_runtime/common/composition/delete.js +3 -1
  69. package/libx/_runtime/common/composition/tree.js +23 -18
  70. package/libx/_runtime/common/composition/update.js +9 -1
  71. package/libx/_runtime/common/composition/utils.js +34 -8
  72. package/libx/_runtime/common/error/frontend.js +6 -1
  73. package/libx/_runtime/common/generic/auth.js +5 -9
  74. package/libx/_runtime/common/generic/crud.js +2 -2
  75. package/libx/_runtime/common/generic/etag.js +11 -8
  76. package/libx/_runtime/common/generic/input.js +3 -3
  77. package/libx/_runtime/common/generic/paging.js +9 -5
  78. package/libx/_runtime/common/generic/put.js +3 -2
  79. package/libx/_runtime/common/generic/sorting.js +3 -3
  80. package/libx/_runtime/common/generic/temporal.js +3 -3
  81. package/libx/_runtime/common/utils/cqn.js +20 -1
  82. package/libx/_runtime/common/utils/cqn2cqn4sql.js +125 -139
  83. package/libx/_runtime/common/utils/csn.js +50 -52
  84. package/libx/_runtime/common/utils/foreignKeyPropagations.js +41 -176
  85. package/libx/_runtime/common/utils/generateOnCond.js +40 -70
  86. package/libx/_runtime/common/utils/{enrichWithKeysFromWhere.js → keys.js} +29 -28
  87. package/libx/_runtime/common/utils/postProcessing.js +3 -0
  88. package/libx/_runtime/common/utils/propagateForeignKeys.js +84 -0
  89. package/libx/_runtime/common/utils/resolveStructured.js +1 -1
  90. package/libx/_runtime/common/utils/resolveView.js +7 -5
  91. package/libx/_runtime/common/utils/rewriteAsterisks.js +94 -0
  92. package/libx/_runtime/common/utils/search2cqn4sql.js +9 -8
  93. package/libx/_runtime/common/utils/template.js +54 -46
  94. package/libx/_runtime/db/Service.js +9 -2
  95. package/libx/_runtime/db/expand/expandCQNToJoin.js +54 -33
  96. package/libx/_runtime/db/expand/rawToExpanded.js +2 -1
  97. package/libx/_runtime/db/generic/arrayed.js +13 -28
  98. package/libx/_runtime/db/generic/create.js +1 -0
  99. package/libx/_runtime/db/generic/input.js +7 -11
  100. package/libx/_runtime/db/generic/integrity.js +2 -2
  101. package/libx/_runtime/db/generic/rewrite.js +2 -5
  102. package/libx/_runtime/db/generic/update.js +1 -0
  103. package/libx/_runtime/db/query/read.js +9 -4
  104. package/libx/_runtime/db/sql-builder/SelectBuilder.js +7 -2
  105. package/libx/_runtime/db/sql-builder/annotations.js +1 -0
  106. package/libx/_runtime/db/utils/columns.js +14 -43
  107. package/libx/_runtime/fiori/generic/activate.js +3 -2
  108. package/libx/_runtime/fiori/generic/before.js +2 -2
  109. package/libx/_runtime/fiori/generic/cancel.js +3 -2
  110. package/libx/_runtime/fiori/generic/delete.js +3 -2
  111. package/libx/_runtime/fiori/generic/edit.js +3 -3
  112. package/libx/_runtime/fiori/generic/new.js +2 -2
  113. package/libx/_runtime/fiori/generic/patch.js +2 -2
  114. package/libx/_runtime/fiori/generic/prepare.js +2 -2
  115. package/libx/_runtime/fiori/generic/read.js +45 -63
  116. package/libx/_runtime/fiori/generic/readOverDraft.js +4 -4
  117. package/libx/_runtime/fiori/uiflex/extensibility/index.cds +15 -0
  118. package/libx/_runtime/fiori/uiflex/extensibility/index.js +148 -0
  119. package/libx/_runtime/fiori/uiflex/handler/transformREAD.js +119 -0
  120. package/libx/_runtime/fiori/uiflex/handler/transformRESULT.js +43 -0
  121. package/libx/_runtime/fiori/uiflex/handler/transformWRITE.js +62 -0
  122. package/libx/_runtime/fiori/uiflex/index.js +35 -0
  123. package/libx/_runtime/fiori/uiflex/utils.js +78 -0
  124. package/libx/_runtime/fiori/utils/handler.js +3 -13
  125. package/libx/_runtime/fiori/utils/where.js +6 -1
  126. package/libx/_runtime/hana/pool.js +12 -11
  127. package/libx/_runtime/hana/search2cqn4sql.js +34 -43
  128. package/libx/_runtime/hana/searchToContains.js +3 -3
  129. package/libx/_runtime/index.js +5 -2
  130. package/libx/_runtime/messaging/AMQPWebhookMessaging.js +1 -1
  131. package/libx/_runtime/messaging/common-utils/AMQPClient.js +16 -3
  132. package/libx/_runtime/messaging/common-utils/connections.js +11 -14
  133. package/libx/_runtime/messaging/common-utils/naming-conventions.js +1 -1
  134. package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +2 -1
  135. package/libx/_runtime/messaging/message-queuing.js +18 -0
  136. package/libx/_runtime/remote/Service.js +20 -4
  137. package/libx/_runtime/remote/utils/client-types.d.ts +7 -0
  138. package/libx/_runtime/remote/utils/client.js +117 -23
  139. package/libx/_runtime/sqlite/Service.js +2 -2
  140. package/libx/_runtime/sqlite/convertAssocToOneManaged.js +1 -3
  141. package/libx/gql/GraphQLAdapter.js +33 -0
  142. package/libx/gql/constants/adapter.js +69 -0
  143. package/libx/gql/constants/cds.js +18 -0
  144. package/libx/gql/constants/graphql.js +33 -0
  145. package/libx/gql/resolvers/crud/create.js +15 -0
  146. package/libx/gql/resolvers/crud/delete.js +24 -0
  147. package/libx/gql/resolvers/crud/index.js +6 -0
  148. package/libx/gql/resolvers/crud/read.js +25 -0
  149. package/libx/gql/resolvers/crud/update.js +31 -0
  150. package/libx/gql/resolvers/crud/utils/index.js +36 -0
  151. package/libx/gql/resolvers/field.js +5 -0
  152. package/libx/gql/resolvers/index.js +7 -0
  153. package/libx/gql/resolvers/mutation.js +23 -0
  154. package/libx/gql/resolvers/parse/ast/enrich.js +51 -0
  155. package/libx/gql/resolvers/parse/ast/fragment.js +11 -0
  156. package/libx/gql/resolvers/parse/ast/fromObject.js +39 -0
  157. package/libx/gql/resolvers/parse/ast/index.js +3 -0
  158. package/libx/gql/resolvers/parse/ast/meta.js +4 -0
  159. package/libx/gql/resolvers/parse/ast/variable.js +7 -0
  160. package/libx/gql/resolvers/parse/ast2cqn/columns.js +42 -0
  161. package/libx/gql/resolvers/parse/ast2cqn/entries.js +31 -0
  162. package/libx/gql/resolvers/parse/ast2cqn/index.js +8 -0
  163. package/libx/gql/resolvers/parse/ast2cqn/limit.js +6 -0
  164. package/libx/gql/resolvers/parse/ast2cqn/orderBy.js +24 -0
  165. package/libx/gql/resolvers/parse/ast2cqn/utils/index.js +3 -0
  166. package/libx/gql/resolvers/parse/ast2cqn/where.js +70 -0
  167. package/libx/gql/resolvers/parse/utils/index.js +8 -0
  168. package/libx/gql/resolvers/query.js +13 -0
  169. package/libx/gql/resolvers/root.js +34 -0
  170. package/libx/gql/schema/generate.js +18 -0
  171. package/libx/gql/schema/index.js +5 -0
  172. package/libx/gql/schema/mutation.js +76 -0
  173. package/libx/gql/schema/query.js +108 -0
  174. package/libx/gql/schema/typeDefMap.js +45 -0
  175. package/libx/gql/schema/utils/index.js +54 -0
  176. package/libx/gql/utils/index.js +12 -0
  177. package/libx/{_runtime/odata/cqn2odata.js → odata/cqn2odata/index.js} +39 -100
  178. package/libx/odata/index.js +80 -0
  179. package/libx/odata/odata2cqn/afterburner.js +170 -0
  180. package/libx/{_runtime/odata/odata2cqn.pegjs → odata/odata2cqn/grammar.pegjs} +102 -123
  181. package/libx/odata/odata2cqn/index.js +3 -0
  182. package/libx/odata/odata2cqn/parser.js +1 -0
  183. package/libx/odata/utils/index.js +64 -0
  184. package/libx/rest/RestAdapter.js +101 -0
  185. package/libx/rest/RestRequest.js +30 -0
  186. package/libx/rest/index.js +3 -0
  187. package/libx/rest/middleware/auth.js +22 -0
  188. package/libx/rest/middleware/content.js +15 -0
  189. package/libx/rest/middleware/create.js +40 -0
  190. package/libx/rest/middleware/delete.js +20 -0
  191. package/libx/rest/middleware/error.js +56 -0
  192. package/libx/rest/middleware/operation.js +39 -0
  193. package/libx/rest/middleware/parse.js +90 -0
  194. package/libx/rest/middleware/read.js +29 -0
  195. package/libx/rest/middleware/update.js +42 -0
  196. package/libx/rest/utils/data.js +65 -0
  197. package/package.json +4 -1
  198. package/server.js +29 -7
  199. package/libx/_runtime/cds-services/services/utils/diff.js +0 -53
  200. package/libx/_runtime/cds-services/util/auditlog.js +0 -247
  201. package/libx/_runtime/cds-services/util/xsenv.js +0 -51
  202. package/libx/_runtime/common/utils/backlinks.js +0 -83
  203. package/libx/_runtime/common/utils/rewriteAsterisk.js +0 -72
  204. package/libx/_runtime/odata/index.js +0 -55
  205. package/libx/_runtime/odata/odata2cqn.js +0 -1
  206. package/libx/_runtime/odata/readToCqn.js +0 -129
  207. package/libx/_runtime/remote/cqn2odata/index.js +0 -2
package/CHANGELOG.md CHANGED
@@ -4,6 +4,143 @@
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.3 - 2021-11-15
8
+
9
+ ### Fixed
10
+
11
+ - `cds run` does not fail if `cds.requires.multitenancy` is explicitly set to `false`
12
+ - Calculation of `DraftIsCreatedByMe` or `DraftIsProcessedByMe` when expanding or navigating to `DraftAdministrativeData`
13
+ - Nested `any` in `$filter` query option
14
+ - Crash on draft activate after draft edit for not existing composition of one, if no explicit DB service is defined
15
+ - Typescript definition of `srv.delete` no longer leads to a duplication error
16
+
17
+ ## Version 5.6.2 - 2021-11-08
18
+
19
+ ### Fixed
20
+
21
+ - Handle arrayed elements using templating mechanism
22
+ - OData requests to `$count` endpoint of ETag enabled entity
23
+ - `cds.test` does no longer crash if executed in `cds repl` on a remote service call
24
+ - Crash on draft activate after draft edit for not existing composition of one
25
+ - Ensure request correlation (with default server)
26
+ - `<entity>.texts` points to real text entity
27
+ - Draft union with expand to to-one and to-many
28
+ - No columns in draft lock statement (i.e., use `SELECT 1`)
29
+
30
+ ## Version 5.6.1 - 2021-11-02
31
+
32
+ ### Fixed
33
+
34
+ - UAA credentials lookup
35
+ - Revert return type validation for `cds.String` for compatibility with older `@sap/cds-mtx` versions
36
+ - Messaging: Ill-defined incoming AMQP messages will not crash the app
37
+ - `cds compile -l` does no longer crash if called without `--to` option
38
+
39
+ ## Version 5.6.0 - 2021-10-29
40
+
41
+ ### Added
42
+
43
+ - New REST protocol adapter (beta)
44
+ + Makes use of the beta OData URL to CQN parser. Hence, almost all OData requests are supported (see limitations below).
45
+ + Activate via `cds.env.features.rest_new_adapter = true`
46
+ + Out of scope (compared to OData protocol adapter):
47
+ + OData query option `$apply`
48
+ + Batch requests (with or without atomicity groups)
49
+ + Draft handling
50
+ - New GraphQL protocol adapter (alpha)
51
+ + Serves single endpoint for all services based on `served` event at `/graphql` (subject to change).
52
+ + Activate via `cds.env.features.graphql = true`
53
+ + Required additional dependencies: `@graphql-tools/schema`, `express-graphql`, and `graphql`
54
+ + Not meant for productive use! For example, authentication and authorization are out of scope.
55
+ - Support of the following features when using beta OData URL to CQN parser (`cds.env.features.odata_new_parser`):
56
+ + REST-style URLs (example: `GET /Foo/1`)
57
+ + `$expand=*` query option on different nested expand levels (`$levels` is not yet supported)
58
+ + draft handling
59
+ + structured keys
60
+ + streaming
61
+ + navigation to primitive properties without `$value` query option
62
+ - 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`)
63
+ - `GET` requests support static values in ON-conditions of composition parents when using unmanaged backlinks
64
+ - `destinationOptions` can be configured for Remote Services
65
+ + Example:
66
+ ```json
67
+ {"cds":{"requires":{
68
+ "S4": {
69
+ "destinationOptions": {
70
+ "selectionStrategy": "subscriberFirst",
71
+ ...
72
+ }
73
+ }
74
+ }}}
75
+ ```
76
+ - `forwardAuthToken` can be configured for Remote Services
77
+ + Example:
78
+ ```json
79
+ {"cds":{"requires":{
80
+ "credentials": {
81
+ "url": "...",
82
+ "forwardAuthToken": true
83
+ }
84
+ }
85
+ }}}
86
+ ```
87
+ - File to store private project settings `.cdsrc-private.json` (should not be checked in source code management)
88
+ - Read additional configuration from JSON files or directory structures using `CDS_CONFIG` env variable
89
+ - Missing typescript definitions for services' `.send` shortcuts `get`, `put`, `post`, `patch`, and `delete`
90
+ - Build VCAP_SERVICES env variable dynamically for compatibility (`cds.env.features.emulate_vcap_services`)
91
+ - GET requests to Remote OData Service are automatically sent as `$batch` if the generated URL is too long
92
+ + Can be configured via `cds.env.remote.max_get_url_length` (beta, default: 1028).
93
+ - Provide ETag in response headers in case of `prefer: return=minimal`
94
+ - Kibana formatter: log the user's id via `cds.env.log.user = true` (beta)
95
+ + Consider the data privacy implications!
96
+ - Experimental support for uiflex running locally on sqlite by setting `cds.requires.extensibility.kind = uiflex`
97
+ - Minified `cds.model` (deactivate via `cds.env.features.skip_unused = false`)
98
+
99
+ ### Changed
100
+
101
+ - 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`.
102
+ + Deactivate during two month grace period via compat feature flag `cds.env.features.keys_into_where = true`
103
+ - Removed duplicate integrity checks
104
+ - Optimized search: Optimize queries for non-localized elements
105
+ - Non-specified columns are resolved at database layer
106
+ - `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
107
+ - Target keys are not included into a body when sending `PATCH` requests to external services
108
+
109
+ ### Fixed
110
+
111
+ - Audit logging of non-string values
112
+ - Query API compilation error when keys start with `{`
113
+ - Handling of wrong Edm.DateTimeOffset values
114
+ - Using UUIDs in search with beta OData URL to CQN parser (`cds.env.features.odata_new_parser`)
115
+ - Runtime exception for READ requests with deeply nested navigation and structured keys, for example:
116
+ `GET foo/Bar/b708ad6c-2dd4-40d5-91c0-2e3eacf306d2/Info/sales(a='1010',b='10',c='00')/functions(functionName='error')`
117
+ - The check for the minimum Node.js version now properly enforces version 12.18, i.e. aborts server startup.
118
+ - `cds.test` fails with a clearer error message if the server wasn't started at all
119
+ - Audit logging for modification of personal or sensitive data when using same entity as a composition child in different parent entities
120
+ - 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
121
+ - Audit logging for entities having arrayed elements
122
+ - Filtering for `cds.Date` on Remote OData V2 services
123
+ - Crash when `rollup` function was used in groupBy in odata requests
124
+ - Or for $filter with IsActiveEntity=true for access to active entities
125
+ - Reading draft-enabled entity with `$expand` targeting non-draft associations
126
+ - Delete with sub-select
127
+ - Runtime exception when streaming property annotated with `@Core.MediaType: 'application/json'`
128
+ - Reading streams via navigation when entity containing large data is a part of a draft-enabled composition tree
129
+ - Read draft entity with nested exists restriction
130
+ - Activate draft of entity having `to-one` and `to-many` compositions
131
+ - Caching issue that causes the OData `omit-values` preference in `Prefer` HTTP headers to misbehaves
132
+ - Deletion of draft instances if multiple draft enabled entities are used within one service
133
+ - Queries with `contains` filter targeting a remote odata v2 service
134
+ - Schema evolution support for nested CDS entities in `cds build`
135
+ - I18n texts with quotes and other special characters get escaped correctly if they appear in XML and Json documents
136
+ - Execution of plain SQL statements on SQLite
137
+ - `Content-Disposition` header is now url encoded
138
+
139
+ ### Removed
140
+
141
+ - Usage of `@sap/xsenv` is superseded with `cds.env` in node.js cds-runtime
142
+ - `@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.
143
+
7
144
  ## Version 5.5.5 - 2021-10-20
8
145
 
9
146
  ### Fixed
@@ -58,6 +195,7 @@
58
195
  ### Added
59
196
 
60
197
  - Support for minified models
198
+ - Messaging: Support for string payloads
61
199
  - Messaging: Webhooks use 'application/json' as the default content type
62
200
  - Messaging: If senders don't use `data` as a property of the payload, then the whole payload is interpreted as `data`
63
201
  - Messaging: Support for `$namespace` placeholer in queue name
@@ -155,7 +293,7 @@
155
293
  - Messaging: In multitenancy mode, messaging artifacts are only deployed to subscribers (unless the service option `deployForProvider` is set to `true`)
156
294
  - Messaging: Incoming messages without corresponding handlers are not acknowledged
157
295
  - 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.
158
- + Deactivate during two month grace period via compact feature flag `cds.env.features.resolve_views = false`
296
+ + Deactivate during two month grace period via compat feature flag `cds.env.features.resolve_views = false`
159
297
  - Use `@sap/cds-compiler`'s `smartId` function to determine whether a reference needs to be quoted.
160
298
  + Allows the use of non-word characters in column names, for example `entity Foo { ![bar/bz]: String; }`.
161
299
  + Support for columns with spaces with feature flag `cds.env.features.spaced_columns`.
@@ -140,7 +140,37 @@ 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
+ * @see [docs](https://cap.cloud.sap/docs/node.js/services#srv-run)
170
+ */
171
+ delete <T>(entity : Definition | string, key?: any) : DELETE<T>
172
+
173
+ // The central method to dispatch events
144
174
  dispatch (msg: EventMessage): Promise<any>
145
175
 
146
176
 
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) {