@sap/cds 5.6.4 → 5.7.4

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 (183) hide show
  1. package/CHANGELOG.md +134 -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 +3 -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 +0 -34
  31. package/lib/deploy.js +25 -17
  32. package/lib/env/defaults.js +3 -1
  33. package/lib/env/index.js +8 -3
  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 +3 -1
  38. package/lib/log/index.js +2 -2
  39. package/lib/req/cds-context.js +79 -0
  40. package/lib/req/context.js +5 -77
  41. package/lib/req/request.js +1 -1
  42. package/lib/serve/Service-api.js +8 -4
  43. package/lib/serve/Service-dispatch.js +0 -7
  44. package/lib/serve/Service-methods.js +6 -8
  45. package/lib/serve/Transaction.js +35 -30
  46. package/lib/serve/adapters.js +1 -4
  47. package/lib/utils/axios.js +1 -1
  48. package/libx/_runtime/audit/Service.js +44 -20
  49. package/libx/_runtime/audit/generic/personal/access.js +16 -11
  50. package/libx/_runtime/audit/generic/personal/modification.js +5 -5
  51. package/libx/_runtime/audit/generic/personal/utils.js +46 -37
  52. package/libx/_runtime/{common/auth → auth}/index.js +21 -7
  53. package/libx/_runtime/{common/auth → auth}/strategies/JWT.js +2 -2
  54. package/libx/_runtime/{common/auth → auth}/strategies/basic.js +2 -2
  55. package/libx/_runtime/{common/auth → auth}/strategies/dummy.js +1 -1
  56. package/libx/_runtime/{common/auth → auth}/strategies/mock.js +2 -2
  57. package/libx/_runtime/{common/auth → auth}/strategies/utils/uaa.js +1 -1
  58. package/libx/_runtime/{common/auth → auth}/strategies/utils/xssec.js +0 -0
  59. package/libx/_runtime/{common/auth → auth}/strategies/xsuaa.js +2 -2
  60. package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +7 -2
  61. package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +0 -7
  62. package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +0 -8
  63. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +3 -4
  64. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +6 -7
  65. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/delete.js +3 -4
  66. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +2 -11
  67. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +16 -6
  68. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +26 -69
  69. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +0 -7
  70. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +3 -66
  71. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +29 -1
  72. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/expandToCQN.js +7 -1
  73. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/readToCQN.js +4 -0
  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/validator/ConditionalRequestValidator.js +0 -8
  78. package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +54 -76
  79. package/libx/_runtime/cds-services/adapter/rest/RestRequest.js +0 -7
  80. package/libx/_runtime/cds-services/adapter/rest/handlers/create.js +3 -6
  81. package/libx/_runtime/cds-services/adapter/rest/handlers/delete.js +3 -6
  82. package/libx/_runtime/cds-services/adapter/rest/handlers/operation.js +3 -6
  83. package/libx/_runtime/cds-services/adapter/rest/handlers/read.js +3 -6
  84. package/libx/_runtime/cds-services/adapter/rest/handlers/update.js +3 -6
  85. package/libx/_runtime/cds-services/adapter/rest/utils/parse-url.js +8 -4
  86. package/libx/_runtime/cds-services/services/Service.js +1 -7
  87. package/libx/_runtime/cds-services/services/utils/columns.js +10 -3
  88. package/libx/_runtime/cds-services/services/utils/compareJson.js +3 -6
  89. package/libx/_runtime/cds-services/services/utils/differ.js +4 -1
  90. package/libx/_runtime/cds-services/services/utils/handlerUtils.js +1 -41
  91. package/libx/_runtime/cds-services/util/assert.js +1 -262
  92. package/libx/_runtime/cds.js +6 -9
  93. package/libx/_runtime/common/aspects/entity.js +1 -1
  94. package/libx/_runtime/common/composition/delete.js +4 -2
  95. package/libx/_runtime/common/composition/update.js +22 -38
  96. package/libx/_runtime/common/composition/utils.js +3 -7
  97. package/libx/_runtime/common/error/standardError.js +11 -0
  98. package/libx/_runtime/common/generic/auth.js +63 -33
  99. package/libx/_runtime/common/generic/crud.js +11 -23
  100. package/libx/_runtime/common/generic/input.js +20 -0
  101. package/libx/_runtime/common/generic/put.js +4 -10
  102. package/libx/_runtime/common/generic/sorting.js +12 -30
  103. package/libx/_runtime/common/i18n/messages.properties +2 -0
  104. package/libx/_runtime/common/perf/index.js +24 -0
  105. package/libx/_runtime/common/utils/cqn.js +58 -1
  106. package/libx/_runtime/common/utils/cqn2cqn4sql.js +298 -121
  107. package/libx/_runtime/common/utils/csn.js +38 -56
  108. package/libx/_runtime/common/utils/entityFromCqn.js +6 -6
  109. package/libx/_runtime/common/utils/resolveView.js +4 -5
  110. package/libx/_runtime/common/utils/rewriteAsterisks.js +46 -5
  111. package/libx/_runtime/common/utils/search2cqn4sql.js +21 -9
  112. package/libx/_runtime/common/utils/structured.js +35 -25
  113. package/libx/_runtime/db/Service.js +0 -6
  114. package/libx/_runtime/db/data-conversion/post-processing.js +22 -22
  115. package/libx/_runtime/db/expand/expand-v2.js +130 -0
  116. package/libx/_runtime/db/expand/expandCQNToJoin.js +57 -75
  117. package/libx/_runtime/db/expand/index.js +3 -1
  118. package/libx/_runtime/db/generic/input.js +52 -10
  119. package/libx/_runtime/db/generic/integrity.js +367 -26
  120. package/libx/_runtime/db/generic/virtual.js +51 -13
  121. package/libx/_runtime/db/query/read.js +12 -8
  122. package/libx/_runtime/db/query/update.js +9 -3
  123. package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +8 -9
  124. package/libx/_runtime/{common → db}/utils/propagateForeignKeys.js +11 -14
  125. package/libx/_runtime/fiori/generic/activate.js +1 -0
  126. package/libx/_runtime/fiori/generic/before.js +2 -1
  127. package/libx/_runtime/fiori/generic/edit.js +1 -0
  128. package/libx/_runtime/fiori/generic/patch.js +1 -1
  129. package/libx/_runtime/fiori/generic/read.js +128 -57
  130. package/libx/_runtime/fiori/uiflex/index.js +1 -1
  131. package/libx/_runtime/fiori/uiflex/{extensibility/index.js → service.js} +3 -3
  132. package/libx/_runtime/fiori/utils/delete.js +7 -1
  133. package/libx/_runtime/hana/Service.js +1 -8
  134. package/libx/_runtime/hana/customBuilder/CustomSelectBuilder.js +5 -14
  135. package/libx/_runtime/hana/execute.js +10 -4
  136. package/libx/_runtime/hana/pool.js +55 -45
  137. package/libx/_runtime/hana/search.js +7 -6
  138. package/libx/_runtime/hana/search2cqn4sql.js +8 -5
  139. package/libx/_runtime/hana/searchToContains.js +3 -1
  140. package/libx/_runtime/index.js +5 -5
  141. package/libx/_runtime/messaging/AMQPWebhookMessaging.js +3 -3
  142. package/libx/_runtime/messaging/Outbox.js +53 -0
  143. package/libx/_runtime/messaging/common-utils/AMQPClient.js +17 -10
  144. package/libx/_runtime/messaging/common-utils/connections.js +14 -9
  145. package/libx/_runtime/messaging/common-utils/waitingTime.js +2 -0
  146. package/libx/_runtime/messaging/enterprise-messaging-shared.js +2 -3
  147. package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +2 -2
  148. package/libx/_runtime/messaging/enterprise-messaging.js +21 -15
  149. package/libx/_runtime/messaging/file-based.js +5 -5
  150. package/libx/_runtime/messaging/message-queuing-utils/options-messaging.js +1 -0
  151. package/libx/_runtime/messaging/message-queuing.js +2 -3
  152. package/libx/_runtime/messaging/outbox/OutboxRunner.js +75 -0
  153. package/libx/_runtime/messaging/outbox/utils.js +192 -0
  154. package/libx/_runtime/messaging/service.js +16 -30
  155. package/libx/_runtime/remote/Service.js +15 -0
  156. package/libx/_runtime/remote/utils/client.js +15 -3
  157. package/libx/_runtime/remote/utils/{dataConversion.js → data.js} +12 -2
  158. package/libx/_runtime/sqlite/Service.js +7 -10
  159. package/libx/_runtime/sqlite/customBuilder/CustomExpressionBuilder.js +19 -0
  160. package/libx/_runtime/sqlite/execute.js +18 -12
  161. package/libx/_runtime/types/api.js +2 -1
  162. package/libx/gql/resolvers/parse/ast2cqn/columns.js +1 -1
  163. package/libx/odata/{odata2cqn/afterburner.js → afterburner.js} +19 -15
  164. package/libx/odata/{cqn2odata/index.js → cqn2odata.js} +1 -1
  165. package/libx/odata/{odata2cqn/grammar.pegjs → grammar.pegjs} +217 -148
  166. package/libx/odata/index.js +21 -13
  167. package/libx/odata/parser.js +1 -0
  168. package/libx/odata/utils.js +57 -0
  169. package/libx/rest/RestAdapter.js +2 -6
  170. package/libx/rest/utils/data.js +1 -6
  171. package/package.json +4 -3
  172. package/server.js +4 -5
  173. package/srv/audit-log.cds +87 -0
  174. package/{libx/_runtime/fiori/uiflex/extensibility/index.cds → srv/flex.cds} +0 -0
  175. package/srv/flex.js +1 -0
  176. package/srv/outbox.cds +11 -0
  177. package/srv/outbox.js +0 -0
  178. package/libx/_runtime/cds-services/adapter/perf/performance.js +0 -104
  179. package/libx/_runtime/cds-services/adapter/perf/performanceMeasurement.js +0 -33
  180. package/libx/odata/odata2cqn/index.js +0 -3
  181. package/libx/odata/odata2cqn/parser.js +0 -1
  182. package/libx/odata/readme.md +0 -1
  183. package/libx/odata/utils/index.js +0 -64
package/CHANGELOG.md CHANGED
@@ -4,6 +4,136 @@
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.4 - 2021-12-22
8
+
9
+ ### Fixed
10
+
11
+ - Complex `@restrict.where: 'exists [...] or (... or ...) or ...'` in draft union scenario no longer crashes the application
12
+ - Sanitization of null values for `cds.RemoteService`
13
+ - Handling of boolean values in draft union scenario with `$expand` query option
14
+ - `_4odata` flag in CQN stays non-enumerable when forwarding to another application service
15
+ - Handling of type references on properties of associations in `cds.minify`
16
+
17
+ ## Version 5.7.3 - 2021-12-16
18
+
19
+ ### Fixed
20
+
21
+ - Message Queuing now accepts `amqp` options
22
+ - OData requests using lambda expressions with `contains` function
23
+ - Result of OData query option `$count=true` when using `$apply`
24
+ - `$filter` with navigation to-one equals value crashes
25
+ - `$skiptoken` query option allows to use arbitrary symbols except of `&` with beta OData URL to CQN parser (`cds.env.features.odata_new_parser`). In this non-integer value case the value will not be parsed into CQN.
26
+ - Function names in `$filter` can now be case insensitive (as per OData 4.01)
27
+ - `$count` in `$expand` caused server to crash
28
+
29
+ ## Version 5.7.2 - 2021-12-09
30
+
31
+ ### Fixed
32
+
33
+ - Instance-based restriction for activation of draft enabled entities
34
+ - `.columns('*')` on projections of remote services using renamed properties
35
+ - GraphQL filters on nested fields are now applied correctly
36
+ - Performance degradation during processing of `where exists`
37
+ - Read drafts via navigation with complex filter expression
38
+
39
+ ## Version 5.7.1 - 2021-12-06
40
+
41
+ ### Fixed
42
+
43
+ - Draft (OData flavors `w4`, `x4` and `v4` with structs): Flags `HasActiveEntity`, `HasDraftEntity`, and `IsActiveEntity` are now included in the HTTP response for GET requests.
44
+ - Instance-based restriction on entities using localized fields in draft
45
+ - Results of actions/functions do not ignore nested data if query options are present
46
+
47
+ ## Version 5.7.0 - 2021-12-03
48
+
49
+ ### Added
50
+
51
+ - Deferred emitting via persistent outbox, enabled through service `outbox` of kind `persistent-outbox`
52
+ - Support for compiler-generated referential constraints (beta)
53
+ + Activate via `cds.env.features.assert_integrity: '<preset>'`
54
+ + Available presets:
55
+ + `off`: no database constraints and no runtime checks
56
+ + `app`: runtime checks by default
57
+ + `db`: database constraints by default
58
+ + "by default": if not excluded, the runtime check or database constraint applies
59
+ + "opt-in": if included, the runtime check or database constraint applies
60
+ + Behavior can be overridden via `@assert.integrity: <true/false/'RT'/'DB'>` on property, entity, or service level (lowest applies)
61
+ - Allow `--with-mocks` in production via `cds.env.features.with_mocks = true`
62
+ - Set media type from content type header while inbound streaming
63
+ - Support for navigations with `$count` in `$filter`, for example `GET Entity?$filter=toMany/$count gt 0`
64
+ - Draft: Generate UUIDs for request payloads to which extra data items are added (without the UUID keys) in a custom application handler.
65
+ - Generate GraphQL schema via `cds compile -2 gql` (alpha)
66
+ - Log requests to remote services if respective log level is set to `debug`
67
+ - Beta OData URL to CQN parser (`cds.env.features.odata_new_parser`):
68
+ + support for `$skiptoken` query option
69
+ + limited support for `$apply` query option
70
+ + Supported are following transformations and their combinations: `aggregate`, `groupby`, `topcount`, `bottomcount`, `filter`, `search`
71
+ + Not supported:
72
+ + Transformations `topsum`, `bottomsum`, `toppercent`, `bottompercent`, `expand`, `concat`, `compute`, `identity`
73
+ + `rollup` and `$all` in `groupby` transformation
74
+ + Filter function `isdefined`
75
+ + Custom aggregation methods, arithmetic operators (`add`, `sub`, `mul` and so on) and keyword `from` in `aggregate` transformation
76
+ + OData vocabulary for Data Aggregation, `@Aggregation.default` annotation
77
+ + Out of scope:
78
+ + Draft handling
79
+ - Out-of-the-box audit logging for draft enabled entities
80
+ - Support for `@sap/instance-manager`'s hybrid mode
81
+ + Enable via `cds.env.features.hybrid_instance_manager`
82
+ + Respective version of `@sap/instance-manager` required
83
+ - `cds.minify()` (alpha) as static method
84
+ - Annotation `@open` for actions in new Rest Adapter
85
+ - 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
86
+
87
+ ### Changed
88
+
89
+ - `if-match` and `if-none-match` headers are ignored for entities without etags
90
+ - Improve response time of `SELECT` queries that check referential integrity by adding an upper bound `LIMIT 1`
91
+ - Leaner implementation for `sap-statistics`
92
+ - Leading and trailing whitespaces are allowed for `$search` query parameter
93
+ - Insert / Update of Composition of one with empty object is not allowed for non UUID keys
94
+ - Search behavior of whitespaces changed as follow:
95
+ + Searches for plain whitespace, for example, `"$search= "` matches the complete data set.
96
+ + Searches for whitespace surrounded by double-quotes, for example, `$search=" "` matches all entries containing whitespaces.
97
+ - In single tenant mode, the default SQLite database is used, regardless of `context.tenant`
98
+ - `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.
99
+ - Relaxed UUIDs in beta URL to CQN parser (`cds.env.features.odata_new_parser`)
100
+ - Authentication strategies `dummy` and `mock` no longer require `passport`
101
+ - In production, debug logs of `cds.DatabaseService` and `cds.RemoteService` have sanitized values
102
+ + Deactivate via `cds.env.log.sanitize_values = false`
103
+
104
+ ### Fixed
105
+
106
+ - Path resolution for references in sub selects
107
+ - Where exists without infix filter, e.g., `@restrict.where: 'exists author'`
108
+ - `@restrict.where: 'exists [...]'` in draft union scenario
109
+ - Select query with path exists predicates e.g., `WHERE EXISTS books[year = 2000].pages[wordcount > 1000]`
110
+ - Proper registration of audit log event handlers
111
+ - Draft: Generate foreign keys for request payloads to which extra data items are added in a custom application handler.
112
+ - `cds build` correctly merges `hdbmigrationtable` files that have multiple new migration versions defined.
113
+ - `cds.test` converts response data of failed requests to JSON to prevent lost error details
114
+ - Instance based restriction for draft enabled entities
115
+ - Delete requests for localized with compositions
116
+ - Ignore input for static and calculated fields during draft activate
117
+ - Clear extension map entry on error during CSN fetching
118
+ - Do not ignore errors during diff calculation
119
+ - Requests to mocked remote service when using custom service name with `.service` property
120
+ - Rollback on already backrolled or committed transactions are ignored
121
+ - Rollback handling in spawned background job
122
+ - `cds.spawn()` throws error if passed options is an instance of `cds.EventContext`
123
+ - Delete `timestamp` from options passed to `cds.spawn()` (transactions create their own timestamp)
124
+ - Type error during programmatic action/function call if no params defined
125
+ - Fully qualified bound actions/ functions in beta URL to CQN parser (`cds.env.features.odata_new_parser`)
126
+ - Draft handling: `GET` requests with navigation via `SiblingEntity` and expand to-one
127
+ - No audit log if sensitive data not selected
128
+ - Kibana formatter: do not log authorization header value
129
+ - Audit logging (`cds.env.features.audit_personal_data`) no longer crashes the application
130
+ + when using the same entity as a composition child in different parent entities
131
+ + when accessing a not existing entity
132
+
133
+ ### Removed
134
+
135
+ - Deprecated feature flags `cds.env.runtime.skipWithParameters` and `cds.env.features.skip_with_parameters`. Use `cds.env.features.with_parameters` instead.
136
+
7
137
  ## Version 5.6.4 - 2021-11-23
8
138
 
9
139
  ### Fixed
@@ -113,6 +243,9 @@
113
243
  + Deactivate during two month grace period via compat feature flag `cds.env.features.keys_into_where = true`
114
244
  - Removed duplicate integrity checks
115
245
  - Optimized search: Optimize queries for non-localized elements
246
+ - 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:
247
+ - 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`.
248
+ - 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.
116
249
  - Non-specified columns are resolved at database layer
117
250
  - `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
118
251
  - Target keys are not included into a body when sending `PATCH` requests to external services
@@ -585,6 +718,7 @@
585
718
  - `SELECT.where(...)` generates CQN with list of values for `in` operator
586
719
  - Always use flag `u` during input validation via `@assert.format`
587
720
  - Intermediate CQN format for lambda expressions with preceding navigation path
721
+ - Better error messages for draft enabled entities
588
722
 
589
723
  ### Fixed
590
724
 
@@ -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
  /**
@@ -204,7 +204,7 @@ export class DatabaseService extends Service {
204
204
 
205
205
  export interface ResultSet extends Array<{}> {}
206
206
 
207
- export class cds_facade {
207
+ export class cds {
208
208
 
209
209
  /**
210
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