@sap/cds 5.6.1 → 5.7.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 (184) hide show
  1. package/CHANGELOG.md +136 -0
  2. package/_i18n/i18n_fr.properties +4 -4
  3. package/apis/cds.d.ts +7 -10
  4. package/apis/connect.d.ts +3 -3
  5. package/apis/core.d.ts +2 -4
  6. package/apis/models.d.ts +2 -3
  7. package/apis/ql.d.ts +0 -1
  8. package/apis/services.d.ts +7 -3
  9. package/bin/build/buildTaskFactory.js +16 -10
  10. package/bin/build/buildTaskProviderFactory.js +3 -3
  11. package/bin/build/constants.js +2 -1
  12. package/bin/build/provider/buildTaskProviderInternal.js +14 -14
  13. package/bin/build/provider/hana/2migration.js +2 -3
  14. package/bin/build/provider/hana/index.js +34 -0
  15. package/bin/build/provider/hana/migrationtable.js +90 -22
  16. package/bin/build/provider/hana/template/undeploy.json +5 -0
  17. package/bin/build/provider/node-cf/index.js +9 -2
  18. package/bin/serve.js +16 -18
  19. package/lib/compile/cdsc.js +15 -5
  20. package/lib/compile/etc/_localized.js +4 -4
  21. package/lib/compile/extend.js +8 -0
  22. package/lib/compile/index.js +3 -1
  23. package/lib/compile/minify.js +61 -0
  24. package/lib/compile/resolve.js +4 -1
  25. package/lib/compile/to/gql.js +9 -0
  26. package/lib/compile/to/sql.js +26 -30
  27. package/lib/connect/index.js +1 -1
  28. package/lib/core/entities.js +0 -3
  29. package/lib/core/infer.js +1 -0
  30. package/lib/core/reflect.js +1 -34
  31. package/lib/deploy.js +25 -17
  32. package/lib/env/defaults.js +3 -1
  33. package/lib/env/index.js +13 -4
  34. package/lib/env/presets.js +38 -0
  35. package/lib/env/requires.js +16 -11
  36. package/lib/index.js +13 -11
  37. package/lib/log/format/kibana.js +4 -2
  38. package/lib/log/index.js +2 -2
  39. package/lib/ql/Whereable.js +1 -0
  40. package/lib/req/cds-context.js +79 -0
  41. package/lib/req/context.js +5 -77
  42. package/lib/req/request.js +1 -1
  43. package/lib/serve/Service-api.js +8 -4
  44. package/lib/serve/Service-dispatch.js +0 -7
  45. package/lib/serve/Service-methods.js +6 -8
  46. package/lib/serve/Transaction.js +35 -30
  47. package/lib/serve/adapters.js +1 -4
  48. package/lib/utils/axios.js +1 -1
  49. package/libx/_runtime/audit/Service.js +44 -20
  50. package/libx/_runtime/audit/generic/personal/access.js +16 -11
  51. package/libx/_runtime/audit/generic/personal/modification.js +5 -5
  52. package/libx/_runtime/audit/generic/personal/utils.js +46 -37
  53. package/libx/_runtime/{common/auth → auth}/index.js +21 -7
  54. package/libx/_runtime/{common/auth → auth}/strategies/JWT.js +2 -2
  55. package/libx/_runtime/{common/auth → auth}/strategies/basic.js +2 -2
  56. package/libx/_runtime/{common/auth → auth}/strategies/dummy.js +1 -1
  57. package/libx/_runtime/{common/auth → auth}/strategies/mock.js +2 -2
  58. package/libx/_runtime/{common/auth → auth}/strategies/utils/uaa.js +1 -1
  59. package/libx/_runtime/{common/auth → auth}/strategies/utils/xssec.js +0 -0
  60. package/libx/_runtime/{common/auth → auth}/strategies/xsuaa.js +2 -2
  61. package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +7 -2
  62. package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +0 -7
  63. package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +0 -8
  64. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +3 -4
  65. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +6 -7
  66. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/delete.js +3 -4
  67. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +2 -11
  68. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +16 -6
  69. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +26 -65
  70. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +0 -7
  71. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +3 -66
  72. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +26 -0
  73. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/readToCQN.js +5 -5
  74. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/utils.js +2 -2
  75. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/UriParser.js +13 -10
  76. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/ConditionalRequestControlCommand.js +0 -7
  77. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/SetResponseHeadersCommand.js +1 -0
  78. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/validator/ConditionalRequestValidator.js +0 -8
  79. package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +18 -15
  80. package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +54 -76
  81. package/libx/_runtime/cds-services/adapter/rest/RestRequest.js +0 -7
  82. package/libx/_runtime/cds-services/adapter/rest/handlers/create.js +3 -6
  83. package/libx/_runtime/cds-services/adapter/rest/handlers/delete.js +3 -6
  84. package/libx/_runtime/cds-services/adapter/rest/handlers/operation.js +3 -6
  85. package/libx/_runtime/cds-services/adapter/rest/handlers/read.js +3 -6
  86. package/libx/_runtime/cds-services/adapter/rest/handlers/update.js +3 -6
  87. package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/index.js +2 -2
  88. package/libx/_runtime/cds-services/adapter/rest/utils/parse-url.js +8 -4
  89. package/libx/_runtime/cds-services/services/Service.js +0 -6
  90. package/libx/_runtime/cds-services/services/utils/columns.js +10 -3
  91. package/libx/_runtime/cds-services/services/utils/compareJson.js +4 -7
  92. package/libx/_runtime/cds-services/services/utils/differ.js +4 -1
  93. package/libx/_runtime/cds-services/services/utils/handlerUtils.js +1 -41
  94. package/libx/_runtime/cds-services/util/assert.js +1 -262
  95. package/libx/_runtime/cds.js +6 -9
  96. package/libx/_runtime/common/aspects/entity.js +1 -1
  97. package/libx/_runtime/common/composition/delete.js +4 -2
  98. package/libx/_runtime/common/composition/update.js +27 -35
  99. package/libx/_runtime/common/composition/utils.js +3 -7
  100. package/libx/_runtime/common/error/standardError.js +11 -0
  101. package/libx/_runtime/common/generic/auth.js +61 -30
  102. package/libx/_runtime/common/generic/crud.js +11 -23
  103. package/libx/_runtime/common/generic/input.js +20 -0
  104. package/libx/_runtime/common/generic/paging.js +2 -2
  105. package/libx/_runtime/common/generic/put.js +4 -10
  106. package/libx/_runtime/common/generic/sorting.js +12 -30
  107. package/libx/_runtime/common/perf/index.js +24 -0
  108. package/libx/_runtime/common/utils/cqn.js +58 -1
  109. package/libx/_runtime/common/utils/cqn2cqn4sql.js +289 -114
  110. package/libx/_runtime/common/utils/csn.js +38 -56
  111. package/libx/_runtime/common/utils/entityFromCqn.js +6 -6
  112. package/libx/_runtime/common/utils/resolveView.js +4 -5
  113. package/libx/_runtime/common/utils/rewriteAsterisks.js +46 -5
  114. package/libx/_runtime/common/utils/search2cqn4sql.js +21 -9
  115. package/libx/_runtime/common/utils/structured.js +35 -25
  116. package/libx/_runtime/db/Service.js +0 -6
  117. package/libx/_runtime/db/expand/expand-v2.js +130 -0
  118. package/libx/_runtime/db/expand/expandCQNToJoin.js +82 -61
  119. package/libx/_runtime/db/expand/index.js +3 -1
  120. package/libx/_runtime/db/generic/arrayed.js +14 -27
  121. package/libx/_runtime/db/generic/input.js +52 -10
  122. package/libx/_runtime/db/generic/integrity.js +367 -26
  123. package/libx/_runtime/db/generic/virtual.js +51 -13
  124. package/libx/_runtime/db/query/update.js +9 -3
  125. package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +8 -9
  126. package/libx/_runtime/{common → db}/utils/propagateForeignKeys.js +11 -14
  127. package/libx/_runtime/fiori/generic/activate.js +1 -0
  128. package/libx/_runtime/fiori/generic/before.js +2 -1
  129. package/libx/_runtime/fiori/generic/edit.js +2 -1
  130. package/libx/_runtime/fiori/generic/patch.js +1 -1
  131. package/libx/_runtime/fiori/generic/read.js +151 -57
  132. package/libx/_runtime/fiori/uiflex/handler/transformRESULT.js +0 -4
  133. package/libx/_runtime/fiori/uiflex/index.js +1 -1
  134. package/libx/_runtime/fiori/uiflex/{extensibility/index.js → service.js} +6 -4
  135. package/libx/_runtime/fiori/utils/delete.js +7 -1
  136. package/libx/_runtime/hana/Service.js +1 -8
  137. package/libx/_runtime/hana/customBuilder/CustomSelectBuilder.js +5 -14
  138. package/libx/_runtime/hana/execute.js +10 -4
  139. package/libx/_runtime/hana/pool.js +55 -45
  140. package/libx/_runtime/hana/search.js +7 -6
  141. package/libx/_runtime/hana/search2cqn4sql.js +8 -5
  142. package/libx/_runtime/hana/searchToContains.js +3 -1
  143. package/libx/_runtime/index.js +5 -5
  144. package/libx/_runtime/messaging/AMQPWebhookMessaging.js +3 -3
  145. package/libx/_runtime/messaging/Outbox.js +53 -0
  146. package/libx/_runtime/messaging/common-utils/AMQPClient.js +17 -10
  147. package/libx/_runtime/messaging/common-utils/connections.js +14 -9
  148. package/libx/_runtime/messaging/common-utils/waitingTime.js +2 -0
  149. package/libx/_runtime/messaging/enterprise-messaging-shared.js +2 -3
  150. package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +2 -2
  151. package/libx/_runtime/messaging/enterprise-messaging.js +21 -15
  152. package/libx/_runtime/messaging/file-based.js +5 -5
  153. package/libx/_runtime/messaging/message-queuing.js +2 -3
  154. package/libx/_runtime/messaging/outbox/OutboxRunner.js +75 -0
  155. package/libx/_runtime/messaging/outbox/utils.js +192 -0
  156. package/libx/_runtime/messaging/service.js +16 -30
  157. package/libx/_runtime/remote/Service.js +21 -2
  158. package/libx/_runtime/remote/utils/client.js +15 -3
  159. package/libx/_runtime/remote/utils/{dataConversion.js → data.js} +12 -2
  160. package/libx/_runtime/sqlite/Service.js +7 -10
  161. package/libx/_runtime/sqlite/customBuilder/CustomExpressionBuilder.js +19 -0
  162. package/libx/_runtime/sqlite/execute.js +18 -12
  163. package/libx/_runtime/types/api.js +2 -1
  164. package/libx/odata/{odata2cqn/afterburner.js → afterburner.js} +28 -16
  165. package/libx/odata/{cqn2odata/index.js → cqn2odata.js} +1 -1
  166. package/libx/odata/{odata2cqn/grammar.pegjs → grammar.pegjs} +182 -118
  167. package/libx/odata/index.js +18 -15
  168. package/libx/odata/parser.js +1 -0
  169. package/libx/odata/utils.js +57 -0
  170. package/libx/rest/RestAdapter.js +2 -6
  171. package/libx/rest/utils/data.js +1 -6
  172. package/package.json +4 -3
  173. package/server.js +13 -10
  174. package/srv/audit-log.cds +87 -0
  175. package/{libx/_runtime/fiori/uiflex/extensibility/index.cds → srv/flex.cds} +0 -0
  176. package/srv/flex.js +1 -0
  177. package/srv/outbox.cds +11 -0
  178. package/srv/outbox.js +0 -0
  179. package/libx/_runtime/cds-services/adapter/perf/performance.js +0 -104
  180. package/libx/_runtime/cds-services/adapter/perf/performanceMeasurement.js +0 -33
  181. package/libx/odata/odata2cqn/index.js +0 -3
  182. package/libx/odata/odata2cqn/parser.js +0 -1
  183. package/libx/odata/readme.md +0 -1
  184. package/libx/odata/utils/index.js +0 -64
package/CHANGELOG.md CHANGED
@@ -4,6 +4,138 @@
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.7.1 - 2021-12-06
8
+
9
+ ### Fixed
10
+
11
+ - Draft (OData flavors `w4`, `x4` and `v4` with structs): Flags `HasActiveEntity`, `HasDraftEntity`, and `IsActiveEntity` are now included in the HTTP response for GET requests.
12
+ - Instance-based restriction on entities using localized fields in draft
13
+ - Results of actions/functions do not ignore nested data if query options are present
14
+
15
+ ## Version 5.7.0 - 2021-12-03
16
+
17
+ ### Added
18
+
19
+ - Deferred emitting via persistent outbox, enabled through service `outbox` of kind `persistent-outbox`
20
+ - Support for compiler-generated referential constraints (beta)
21
+ + Activate via `cds.env.features.assert_integrity: '<preset>'`
22
+ + Available presets:
23
+ + `off`: no database constraints and no runtime checks
24
+ + `app`: runtime checks by default
25
+ + `db`: database constraints by default
26
+ + "by default": if not excluded, the runtime check or database constraint applies
27
+ + "opt-in": if included, the runtime check or database constraint applies
28
+ + Behavior can be overridden via `@assert.integrity: <true/false/'RT'/'DB'>` on property, entity, or service level (lowest applies)
29
+ - Allow `--with-mocks` in production via `cds.env.features.with_mocks = true`
30
+ - Set media type from content type header while inbound streaming
31
+ - Support for navigations with `$count` in `$filter`, for example `GET Entity?$filter=toMany/$count gt 0`
32
+ - Draft: Generate UUIDs for request payloads to which extra data items are added (without the UUID keys) in a custom application handler.
33
+ - Generate GraphQL schema via `cds compile -2 gql` (alpha)
34
+ - Log requests to remote services if respective log level is set to `debug`
35
+ - Beta OData URL to CQN parser (`cds.env.features.odata_new_parser`):
36
+ + support for `$skiptoken` query option
37
+ + limited support for `$apply` query option
38
+ + Supported are following transformations and their combinations: `aggregate`, `groupby`, `topcount`, `bottomcount`, `filter`, `search`
39
+ + Not supported:
40
+ + Transformations `topsum`, `bottomsum`, `toppercent`, `bottompercent`, `expand`, `concat`, `compute`, `identity`
41
+ + `rollup` and `$all` in `groupby` transformation
42
+ + Filter function `isdefined`
43
+ + Custom aggregation methods, arithmetic operators (`add`, `sub`, `mul` and so on) and keyword `from` in `aggregate` transformation
44
+ + OData vocabulary for Data Aggregation, `@Aggregation.default` annotation
45
+ + Out of scope:
46
+ + Draft handling
47
+ - Out-of-the-box audit logging for draft enabled entities
48
+ - Support for `@sap/instance-manager`'s hybrid mode
49
+ + Enable via `cds.env.features.hybrid_instance_manager`
50
+ + Respective version of `@sap/instance-manager` required
51
+ - `cds.minify()` (alpha) as static method
52
+ - Annotation `@open` for actions in new Rest Adapter
53
+ - Audit logging (`cds.env.features.audit_personal_data`) supports annotation `@PersonalData.EntitySemantics: 'Other'` and allows an arbitrary composition of entities with respect to `@PersonalData.EntitySemantics` annotations
54
+
55
+ ### Changed
56
+
57
+ - `if-match` and `if-none-match` headers are ignored for entities without etags
58
+ - Improve response time of `SELECT` queries that check referential integrity by adding an upper bound `LIMIT 1`
59
+ - Leaner implementation for `sap-statistics`
60
+ - Leading and trailing whitespaces are allowed for `$search` query parameter
61
+ - Insert / Update of Composition of one with empty object is not allowed for non UUID keys
62
+ - Search behavior of whitespaces changed as follow:
63
+ + Searches for plain whitespace, for example, `"$search= "` matches the complete data set.
64
+ + Searches for whitespace surrounded by double-quotes, for example, `$search=" "` matches all entries containing whitespaces.
65
+ - In single tenant mode, the default SQLite database is used, regardless of `context.tenant`
66
+ - `cds build` for Node.js projects now copies `package-lock.json` files into the staging folder (usually `gen/srv`). This allows the execution of `npm ci` there.
67
+ - Relaxed UUIDs in beta URL to CQN parser (`cds.env.features.odata_new_parser`)
68
+ - Authentication strategies `dummy` and `mock` no longer require `passport`
69
+ - In production, debug logs of `cds.DatabaseService` and `cds.RemoteService` have sanitized values
70
+ + Deactivate via `cds.env.log.sanitize_values = false`
71
+
72
+ ### Fixed
73
+
74
+ - Path resolution for references in sub selects
75
+ - Where exists without infix filter, e.g., `@restrict.where: 'exists author'`
76
+ - `@restrict.where: 'exists [...]'` in draft union scenario
77
+ - Select query with path exists predicates e.g., `WHERE EXISTS books[year = 2000].pages[wordcount > 1000]`
78
+ - Proper registration of audit log event handlers
79
+ - Draft: Generate foreign keys for request payloads to which extra data items are added in a custom application handler.
80
+ - `cds build` correctly merges `hdbmigrationtable` files that have multiple new migration versions defined.
81
+ - `cds.test` converts response data of failed requests to JSON to prevent lost error details
82
+ - Instance based restriction for draft enabled entities
83
+ - Delete requests for localized with compositions
84
+ - Ignore input for static and calculated fields during draft activate
85
+ - Clear extension map entry on error during CSN fetching
86
+ - Do not ignore errors during diff calculation
87
+ - Requests to mocked remote service when using custom service name with `.service` property
88
+ - Rollback on already backrolled or committed transactions are ignored
89
+ - Rollback handling in spawned background job
90
+ - `cds.spawn()` throws error if passed options is an instance of `cds.EventContext`
91
+ - Delete `timestamp` from options passed to `cds.spawn()` (transactions create their own timestamp)
92
+ - Type error during programmatic action/function call if no params defined
93
+ - Fully qualified bound actions/ functions in beta URL to CQN parser (`cds.env.features.odata_new_parser`)
94
+ - Draft handling: `GET` requests with navigation via `SiblingEntity` and expand to-one
95
+ - No audit log if sensitive data not selected
96
+ - Kibana formatter: do not log authorization header value
97
+ - Audit logging (`cds.env.features.audit_personal_data`) no longer crashes the application
98
+ + when using the same entity as a composition child in different parent entities
99
+ + when accessing a not existing entity
100
+
101
+ ### Removed
102
+
103
+ - Deprecated feature flags `cds.env.runtime.skipWithParameters` and `cds.env.features.skip_with_parameters`. Use `cds.env.features.with_parameters` instead.
104
+
105
+ ## Version 5.6.4 - 2021-11-23
106
+
107
+ ### Fixed
108
+
109
+ - Preserve log level in Kibana formatter
110
+ - RFC 3986 compliant segment recognition in beta URL to CQN parser (`cds.env.features.odata_new_parser`)
111
+ - Support for `$skiptoken` OData query option when using beta URL to CQN parser (`cds.env.features.odata_new_parser`)
112
+ - OData requests with `$skip` and without `$top` query option to services with defined default limit (`cds.query.limit.default`)
113
+ - Creating entities with binary keys. Currently the binary keys may be provided only as Node.js `Buffer` instances using a custom handler.
114
+ - Requests with payload containing nested arrayed elements no longer crash the application
115
+
116
+ ## Version 5.6.3 - 2021-11-15
117
+
118
+ ### Fixed
119
+
120
+ - `cds run` does not fail if `cds.requires.multitenancy` is explicitly set to `false`
121
+ - Calculation of `DraftIsCreatedByMe` or `DraftIsProcessedByMe` when expanding or navigating to `DraftAdministrativeData`
122
+ - Nested `any` in `$filter` query option
123
+ - Crash on draft activate after draft edit for not existing composition of one, if no explicit DB service is defined
124
+ - Typescript definition of `srv.delete` no longer leads to a duplication error
125
+
126
+ ## Version 5.6.2 - 2021-11-08
127
+
128
+ ### Fixed
129
+
130
+ - Handle arrayed elements using templating mechanism
131
+ - OData requests to `$count` endpoint of ETag enabled entity
132
+ - `cds.test` does no longer crash if executed in `cds repl` on a remote service call
133
+ - Crash on draft activate after draft edit for not existing composition of one
134
+ - Ensure request correlation (with default server)
135
+ - `<entity>.texts` points to real text entity
136
+ - Draft union with expand to to-one and to-many
137
+ - No columns in draft lock statement (i.e., use `SELECT 1`)
138
+
7
139
  ## Version 5.6.1 - 2021-11-02
8
140
 
9
141
  ### Fixed
@@ -79,6 +211,9 @@
79
211
  + Deactivate during two month grace period via compat feature flag `cds.env.features.keys_into_where = true`
80
212
  - Removed duplicate integrity checks
81
213
  - Optimized search: Optimize queries for non-localized elements
214
+ - OData to CQN parsing changed to enable remote service consumption. As a side effect, application code in `srv.on('READ', handler)` custom handlers relaying on CQN might need to be adapted. The following has changed:
215
+ - Previously, columns in `req.query.SELECT.columns` were always defined. Now, in case there is no `$select` and `$expand` query options in the OData query, `req.query.SELECT.columns` is `undefined`.
216
+ - Previously, if the `$expand` query option was specified in the OData query, all elements of the expanded navigation property were listed explicitly in the CQN query. Now, an `*` (asterisk) is listed instead.
82
217
  - Non-specified columns are resolved at database layer
83
218
  - `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
84
219
  - Target keys are not included into a body when sending `PATCH` requests to external services
@@ -551,6 +686,7 @@
551
686
  - `SELECT.where(...)` generates CQN with list of values for `in` operator
552
687
  - Always use flag `u` during input validation via `@assert.format`
553
688
  - Intermediate CQN format for lambda expressions with preceding navigation path
689
+ - Better error messages for draft enabled entities
554
690
 
555
691
  ### Fixed
556
692
 
@@ -26,16 +26,16 @@
26
26
  #----------------------------------------------------------------------------------------------------------------------
27
27
 
28
28
  #XTIT: Created By (Answer to: "Which user has created a certain entity?")
29
- CreatedBy=Cr\u00E9\u00E9(e) par
29
+ CreatedBy=Auteur de la cr\u00E9ation
30
30
 
31
31
  #XTIT: Created On (Answer to: "When has a certain entity been created?")
32
- CreatedAt=Cr\u00E9\u00E9(e) le
32
+ CreatedAt=Date de cr\u00E9ation
33
33
 
34
34
  #XTIT: Changed By (Answer to: "Which user has changed a certain entity?")
35
- ChangedBy=Modifi\u00E9(e) par
35
+ ChangedBy=Auteur de la modification
36
36
 
37
37
  #XTIT: Changed On (Answer to: "When has a certain entity been changed?")
38
- ChangedAt=Modifi\u00E9(e) le
38
+ ChangedAt=Date de modification
39
39
 
40
40
  #XTIT: Currency
41
41
  Currency=Devise
package/apis/cds.d.ts CHANGED
@@ -1,14 +1,11 @@
1
- declare type cds_facade =
2
- import ('./core')
3
- & import ('./models')
4
- & import ('./connect')
5
- & import ('./serve')
6
- & import ('./ql').cds_ql
7
- & import ('./services').cds_facade
8
- & import ('./services').QueryAPI
9
-
10
1
  declare global {
11
- const cds : cds_facade
2
+ const cds : import ('./core')
3
+ & import ('./models')
4
+ & import ('./connect')
5
+ & import ('./serve')
6
+ & import ('./ql').cds_ql
7
+ & import ('./services').cds
8
+ & import ('./services').QueryAPI
12
9
  class SELECT<T> extends cds.ql.SELECT<T>{}
13
10
  class INSERT<T> extends cds.ql.INSERT<T>{}
14
11
  class UPDATE<T> extends cds.ql.UPDATE<T>{}
package/apis/connect.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { Service } from "./services"
2
- import * as cds from './cds'
2
+ import * as cds_facade from './cds'
3
3
 
4
- export = cds_connect
5
- declare class cds_connect {
4
+ export = cds
5
+ declare class cds {
6
6
 
7
7
  connect : {
8
8
  /**
package/apis/core.d.ts CHANGED
@@ -1,11 +1,9 @@
1
1
  // import types from '../lib/core'
2
2
  import { ReflectedModel, LinkedModel, LinkedDefinition } from './reflect'
3
3
  import { CSN as csn, Definition } from "./csn"
4
- import { Query as cqn } from "./cqn"
5
- import { EventEmitter } from "events";
6
4
 
7
- export = cds_core
8
- declare class cds_core extends EventEmitter {
5
+ export = cds
6
+ declare class cds {
9
7
 
10
8
  /**
11
9
  * Turns the given plain CSN model into a linked model
package/apis/models.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import edm from "@sap/cds-compiler/lib/edm/edm"
2
1
  import { Query, expr, _xpr } from "./cqn"
3
2
  import { CSN } from "./csn"
4
3
 
@@ -30,8 +29,8 @@ type EDMX = XML
30
29
  type filename = string
31
30
 
32
31
 
33
- export = cds_models
34
- declare class cds_models {
32
+ export = cds
33
+ declare class cds {
35
34
 
36
35
  /**
37
36
  * Provides a set of methods to parse a given model, query or expression.
package/apis/ql.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import {Definition} from "./csn"
2
2
  import * as CQN from "./cqn"
3
- import { STATUS_CODES } from "http"
4
3
 
5
4
  export type Query = CQN.Query
6
5
 
@@ -64,8 +64,8 @@ export class QueryAPI {
64
64
  * Starts or joins a transaction
65
65
  * @see [docs](https://cap.cloud.sap/docs/node.js/services#srv-tx)
66
66
  */
67
- tx (context : object) : Transaction
68
- transaction (context : object) : Transaction
67
+ tx (context? : object) : Transaction
68
+ transaction (context? : object) : Transaction
69
69
  }
70
70
 
71
71
  /**
@@ -165,6 +165,10 @@ export class Service extends QueryAPI {
165
165
  * @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-send)
166
166
  */
167
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>
168
172
 
169
173
  // The central method to dispatch events
170
174
  dispatch (msg: EventMessage): Promise<any>
@@ -200,7 +204,7 @@ export class DatabaseService extends Service {
200
204
 
201
205
  export interface ResultSet extends Array<{}> {}
202
206
 
203
- export class cds_facade {
207
+ export class cds {
204
208
 
205
209
  /**
206
210
  * @see [capire docs](https://cap.cloud.sap/docs/node.js/services)
@@ -31,7 +31,7 @@ class BuildTaskFactory {
31
31
  buildOptions.target = path.resolve(buildOptions.root, this.env.build.target)
32
32
 
33
33
  // log build tasks
34
- this.logger.log(`[cds] - the following build tasks will be executed`)
34
+ this.logger.log(`the following build tasks will be executed`)
35
35
  let tasksOutput = " {\n \"build\": {\n \"target\": \"" + this.env.build.target + "\",\n \"tasks\": ["
36
36
  for (let i = 0; i < tasks.length; i++) {
37
37
  tasksOutput += "\n " + BuildTaskFactory._stringifyTask(tasks[i]) + (i + 1 < tasks.length ? "," : "")
@@ -63,7 +63,7 @@ class BuildTaskFactory {
63
63
 
64
64
  async _createTasks(providerFactory) {
65
65
  const buildOptions = providerFactory.buildOptions
66
- this.logger.log(`[cds] - determining build tasks for project [${buildOptions.root}].`)
66
+ this.logger.log(`determining build tasks for project [${buildOptions.root}].`)
67
67
 
68
68
  let tasks = this._getExistingTasks()
69
69
  if (tasks.length === 0) {
@@ -118,7 +118,7 @@ class BuildTaskFactory {
118
118
 
119
119
  // Java projects use "." as the default build target folder
120
120
  if (this._hasJavaNature(buildOptions.root, srv) && this._adaptBuildTargetSettingForJava(buildOptions.root)) {
121
- this.logger.debug("[cds] - using inplace build for java project instead of default staging build")
121
+ this.logger.debug("using inplace build for java project instead of default staging build")
122
122
  }
123
123
  buildOptions.target = path.resolve(buildOptions.root, this.env.build.target)
124
124
  }
@@ -130,7 +130,7 @@ class BuildTaskFactory {
130
130
  this.cds.resolve.cache = {}
131
131
 
132
132
  const modelPaths = this.cds.resolve("*", false)
133
- return BuildTaskFactory._pushModelPaths(projectPath, [], modelPaths)
133
+ return this._pushModelPaths(projectPath, [], modelPaths)
134
134
  }
135
135
 
136
136
  /**
@@ -241,17 +241,23 @@ class BuildTaskFactory {
241
241
  return taskOptions
242
242
  }
243
243
 
244
- static _pushModelPaths(projectPath, model, ...modelPaths) {
244
+ _pushModelPaths(projectPath, model, ...modelPaths) {
245
245
  model = new Set(model)
246
246
  // may contain nested arrays
247
247
  modelPaths = BuildTaskFactory._flatten(modelPaths)
248
-
248
+ const { roots } = this.cds.env
249
249
  modelPaths.forEach(m => {
250
250
  if (m && !model.has(m) && !model.has(m + "/")) {
251
- const dir = path.resolve(projectPath, m)
252
- if (fs.existsSync(dir)) {
253
- model.add(BuildTaskFactory._normalizePath(m))
254
- } else if (fs.existsSync(dir + FILE_EXT_CDS)) { //might be cds file name, compability to old build configs
251
+ // filter root model paths that do not exist
252
+ // other entries are added as is, e.g. reuse model entries
253
+ if (roots.includes(m)) {
254
+ const dir = path.resolve(projectPath, m)
255
+ if (fs.existsSync(dir)) {
256
+ model.add(BuildTaskFactory._normalizePath(m))
257
+ } else if (fs.existsSync(dir + FILE_EXT_CDS)) { //might be cds file name, compability to old build configs
258
+ model.add(m)
259
+ }
260
+ } else {
255
261
  model.add(m)
256
262
  }
257
263
  }
@@ -56,7 +56,7 @@ class BuildTaskProviderFactory {
56
56
  }
57
57
 
58
58
  async lookupTasks() {
59
- this.logger.debug("[cds] - Determining CDS build tasks from CDS configuration - applying defaults")
59
+ this.logger.debug("determining CDS build tasks from CDS configuration - applying defaults")
60
60
  let tasks = []
61
61
  await Promise.all(this.providers.map(async (provider) => {
62
62
  let pluginTasks = await this._lookupTasks(provider)
@@ -81,14 +81,14 @@ class BuildTaskProviderFactory {
81
81
  createHandler(task) {
82
82
  const BuildTaskHandlerClass = this.loadHandler(task)
83
83
  const resolvedTask = this.resolveTask(task)
84
- this.logger._debug && this.logger.debug(`[cds] - loaded build task handler [${resolvedTask.use}]`)
84
+ this.logger._debug && this.logger.debug(`loaded build task handler [${resolvedTask.use}]`)
85
85
 
86
86
  const handler = new BuildTaskHandlerClass()
87
87
  handler._task = resolvedTask
88
88
  handler._cds = this.cds
89
89
  handler._logger = this.logger
90
90
  handler._buildOptions = this.buildOptions
91
- this.logger._debug && this.logger.debug(`[cds] - created BuildTaskHandler [${resolvedTask.use}]`)
91
+ this.logger._debug && this.logger.debug(`created BuildTaskHandler [${resolvedTask.use}]`)
92
92
  return handler
93
93
  }
94
94
 
@@ -31,7 +31,8 @@ exports.CONTENT_DEFAULT_CSN = "contentDefaultCsn" // create default CS
31
31
  exports.CONTENT_EDMX = "contentEdmx" // create EDMX for required languages
32
32
  exports.CONTENT_MANIFEST = "contentManifest" // create manifest.yml and .cfignore files
33
33
  exports.CONTENT_PACKAGE_JSON = "contentPackageJson" // create package.json file if not existing, or modify existing package.json
34
- exports.CONTENT_HDBTABLEDATA = "contentHdbtabledata" // create .hdbtabledata files for .csv files if not existing
34
+ exports.CONTENT_PACKAGELOCK_JSON = "contentPackageLockJson" // copy package-lock.json file if existing
35
+ exports.CONTENT_HDBTABLEDATA = "contentHdbtabledata" // create .hdbtabledata files for .csv files if not existing
35
36
 
36
37
  exports.FOLDER_GEN = "gen"
37
38
  exports.FILE_EXT_CDS = ".cds"
@@ -62,7 +62,7 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
62
62
  }
63
63
 
64
64
  async _createTasks(buildOptions) { // NOSONAR
65
- this.logger.debug("[cds] - Determining CDS build tasks from CDS configuration - applying defaults")
65
+ this.logger.debug("determining CDS build tasks from CDS configuration - applying defaults")
66
66
  const { root: projectPath } = buildOptions
67
67
  let tasks = []
68
68
  let db = typeof this.env.folders.db === "string" ? [BuildTaskProviderInternal._normalizePath(this.env.folders.db)] : this.env.folders.db
@@ -87,7 +87,7 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
87
87
  tasks.push(dbTask)
88
88
  }
89
89
  } else {
90
- this.logger.log(`[cds] - project doesn't have a database module [${this.env.folders.db}]`)
90
+ this.logger.log(`project doesn't have a database module [${this.env.folders.db}]`)
91
91
  }
92
92
 
93
93
  if (srv) {
@@ -117,7 +117,7 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
117
117
  }
118
118
  }
119
119
  } else {
120
- this.logger.log(`[cds] - project doesn't have a service module '${this.env.folders.srv}'`)
120
+ this.logger.log(`project doesn't have a service module '${this.env.folders.srv}'`)
121
121
  }
122
122
 
123
123
  // create mtx build task for node applications
@@ -135,11 +135,11 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
135
135
  }
136
136
 
137
137
  _createDbTask(projectPath, src, taskOptions, buildOptions) {
138
- this.logger.debug("[cds] - Determining database kind.")
138
+ this.logger.debug("determining database kind.")
139
139
  let task = null
140
140
 
141
141
  if (this._useHana(projectPath, buildOptions)) {
142
- this.logger.debug("[cds] - Found HANA database.")
142
+ this.logger.debug("found HANA database.")
143
143
  // legacy build supports dest property
144
144
  const compileDest = this.env.get("data.dest")
145
145
  if (compileDest) {
@@ -154,7 +154,7 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
154
154
  options: taskOptions
155
155
  }
156
156
  } else {
157
- this.logger.debug("[cds] - Found sqlite database - skipping HANA build task")
157
+ this.logger.debug("found sqlite database - skipping HANA build task")
158
158
  }
159
159
  return task
160
160
  }
@@ -179,28 +179,28 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
179
179
  }
180
180
 
181
181
  _createMtxTask(srv) {
182
- this.logger.debug("[cds] - Determining single or multi-tenant strategy.")
182
+ this.logger.debug("determining single or multi-tenant strategy.")
183
183
  let task = null
184
184
 
185
185
  if (this.env.get("requires.multitenancy") && (this.env.get("requires.db.kind") === "hana" || this.env.get("requires.db.dialect") === "hana")) {
186
- this.logger.debug("[cds] - Found multi-tenant app.")
186
+ this.logger.debug("found multi-tenant app.")
187
187
  task = {
188
188
  src: ".",
189
189
  for: BUILD_TASK_MTX,
190
190
  dest: srv
191
191
  }
192
192
  } else {
193
- this.logger.debug("[cds] - Found single-tenant app - skipping mtx build task")
193
+ this.logger.debug("found single-tenant app - skipping mtx build task")
194
194
  }
195
195
  return task
196
196
  }
197
197
 
198
198
  _createSrvTask(projectPath, src, taskOptions) {
199
- this.logger.debug("[cds] - Determining implementation technology")
199
+ this.logger.debug("fetermining implementation technology")
200
200
  let task = this._createJavaTask(projectPath, src, taskOptions)
201
201
 
202
202
  if (!task) {
203
- this.logger.debug("[cds] - Found implementation technology node")
203
+ this.logger.debug("found implementation technology node")
204
204
  task = {
205
205
  src: src,
206
206
  for: BUILD_TASK_NODE,
@@ -212,7 +212,7 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
212
212
 
213
213
  _createJavaTask(projectPath, src, taskOptions) {
214
214
  if (this._hasJavaNature(projectPath, src)) {
215
- this.logger.debug("[cds] - Found implementation technology java")
215
+ this.logger.debug("found implementation technology java")
216
216
  // legacy build supports dest property
217
217
  const compileDest = this.env.get("service.dest")
218
218
  if (compileDest) {
@@ -237,7 +237,7 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
237
237
  */
238
238
  _createFioriTasks(projectPath, fioriSrvOptions) {
239
239
  let tasks = []
240
- this.logger.debug("[cds] - Determining fiori modules - matching modules */webapp/manifest.json")
240
+ this.logger.debug("determining fiori modules - matching modules */webapp/manifest.json")
241
241
  // fiori-app build-tasks
242
242
  let appDirs = this.env.ui && this.env.ui.apps ? this.env.ui.apps : undefined
243
243
  if (!appDirs) {
@@ -263,7 +263,7 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
263
263
  return appDir
264
264
  })
265
265
  }
266
- this.logger._debug && this.logger.debug(`[cds] - Found fiori app paths [${appDirs}]`)
266
+ this.logger._debug && this.logger.debug(`found fiori app paths [${appDirs}]`)
267
267
  appDirs.forEach(appDir => {
268
268
  appDir = BuildTaskProviderInternal._normalizePath(appDir)
269
269
  let modelPaths = this._resolveModel(path.resolve(projectPath, appDir))
@@ -4,8 +4,7 @@ const { getProperty, BuildError } = require('../../util')
4
4
  const { getArtifactCdsPersistenceName } = require('@sap/cds-compiler')
5
5
  const { LOG_MODULE_NAMES } = require('../../constants')
6
6
  const cdscVersion = `-- generated by cds-compiler version ${require('@sap/cds-compiler/package.json').version}`
7
- const cds = require('../../cds'), minified = csn => cds.linked(csn).minified()
8
- const { compiler: cdsc } = cds
7
+ const cds = require('../../cds'), { compiler: cdsc } = cds
9
8
  let logger = cds.log(LOG_MODULE_NAMES)
10
9
 
11
10
  module.exports = async (model, lastDevVersion, srcPath, options = {}) => {
@@ -35,7 +34,7 @@ module.exports = async (model, lastDevVersion, srcPath, options = {}) => {
35
34
 
36
35
  function _toHdiMigration(model, lastDevVersion, journalFileNames, options) {
37
36
  options.sqlChangeMode = getProperty(options, 'hana.journal.change-mode')
38
- const result = cdsc.to.hdi.migration(minified(model), options, lastDevVersion);
37
+ const result = cdsc.to.hdi.migration(cds.minify(model), options, lastDevVersion);
39
38
  if (logger._debug) {
40
39
  logger.debug('cdsc.to.hdi.migration returned')
41
40
  for (const { name, suffix, sql } of result.definitions) {
@@ -22,6 +22,7 @@ const FILE_NAME_HDINAMESPACE = ".hdinamespace"
22
22
  const FILE_NAME_PACKAGE_JSON = "package.json"
23
23
  const FILE_NAME_MANIFEST_YML = "manifest.yml"
24
24
  const PATH_LAST_DEV_CSN = "last-dev/csn.json"
25
+ const FILE_NAME_UNDEPLOY_JSON = "undeploy.json"
25
26
 
26
27
  // add well-known types supported by HANA Cloud Edition - see also https://github.wdf.sap.corp/cap/issues/issues/8056
27
28
  const REQUIRED_PLUGIN_TYPES = [FILE_EXT_CSV, FILE_EXT_HDBTABLEDATA, FILE_EXT_HDBTABLE, ".hdbview", ".hdbindex", ".hdbconstraint"]
@@ -64,6 +65,8 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
64
65
  await this._copyNativeContent(src, dest)
65
66
  await this._writeHdiConfig(plugins)
66
67
  await this._writeHdiNamespace()
68
+ // TODO disabled as this contradicts the MTX domain concept which allows partial app deployments
69
+ //await this._writeUndeployJson()
67
70
 
68
71
  if (this.hasBuildOption(CONTENT_HDBTABLEDATA, true)) {
69
72
  await this._compileToHdbtabledata(model, dest)
@@ -344,6 +347,37 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
344
347
  return await this.write(content).to(hdiNamespace)
345
348
  }
346
349
 
350
+ /**
351
+ * Create undeploy.json file in <dest> folder of db module.
352
+ */
353
+ async _writeUndeployJson() {
354
+ if (this.isStagingBuild()) {
355
+ // see issue #64 - add .hdinamespace file to prevent HDI from adding gen/ folder to the namespace.
356
+ const undeployJsonDest = path.join(this.task.dest, FILE_NAME_UNDEPLOY_JSON)
357
+ const undeployJsonSrc = path.join(this.task.src, FILE_NAME_UNDEPLOY_JSON)
358
+ const templateEntries = await this._readTemplateAsJson(FILE_NAME_UNDEPLOY_JSON)
359
+ let newEntries = []
360
+ if (await fs.pathExists(undeployJsonSrc)) {
361
+ newEntries = await fs.readJSON(undeployJsonSrc, 'utf-8')
362
+ newEntries = Array.isArray(newEntries) ? newEntries : []
363
+ templateEntries.forEach(entry => {
364
+ if (!newEntries.includes(entry)) {
365
+ newEntries.push(entry)
366
+ }
367
+ })
368
+ } else {
369
+ newEntries = templateEntries
370
+ }
371
+ // formatted output
372
+ let content = '[\n'
373
+ for (let i = 0; i < newEntries.length; i++) {
374
+ content += ` "${newEntries[i]}"${i + 1 < newEntries.length ? ',' : ''}\n`
375
+ }
376
+ content += ']'
377
+ await this.write(content).to(undeployJsonDest)
378
+ }
379
+ }
380
+
347
381
  /**
348
382
  * Create .cfignore file only for staging build.
349
383
  * This is to have a fast-turnaround at development