@sap/cds 5.4.3 → 5.5.0

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 (228) hide show
  1. package/CHANGELOG.md +239 -2
  2. package/apis/ql.d.ts +17 -15
  3. package/app/index.js +1 -1
  4. package/bin/build/buildTaskEngine.js +26 -42
  5. package/bin/build/buildTaskFactory.js +6 -10
  6. package/bin/build/buildTaskHandler.js +2 -4
  7. package/bin/build/buildTaskProvider.js +3 -1
  8. package/bin/build/buildTaskProviderFactory.js +9 -15
  9. package/bin/build/constants.js +15 -3
  10. package/bin/build/index.js +5 -4
  11. package/bin/build/mtaUtil.js +8 -11
  12. package/bin/build/provider/buildTaskHandlerEdmx.js +63 -6
  13. package/bin/build/provider/buildTaskHandlerInternal.js +2 -34
  14. package/bin/build/provider/buildTaskProviderInternal.js +16 -42
  15. package/bin/build/provider/fiori/index.js +13 -24
  16. package/bin/build/provider/hana/2migration.js +17 -15
  17. package/bin/build/provider/hana/2tabledata.js +52 -48
  18. package/bin/build/provider/hana/index.js +27 -25
  19. package/bin/build/provider/hana/migrationtable.js +91 -67
  20. package/bin/build/provider/java-cf/index.js +14 -24
  21. package/bin/build/provider/mtx/index.js +12 -14
  22. package/bin/build/provider/node-cf/index.js +18 -32
  23. package/bin/cds.js +5 -5
  24. package/bin/serve.js +29 -23
  25. package/bin/version.js +0 -1
  26. package/lib/compile/etc/_localized.js +4 -9
  27. package/lib/compile/for/sql.js +5 -2
  28. package/lib/compile/parse.js +25 -17
  29. package/lib/compile/to/srvinfo.js +2 -1
  30. package/lib/connect/bindings.js +2 -1
  31. package/lib/connect/index.js +48 -49
  32. package/lib/core/classes.js +1 -1
  33. package/lib/core/reflect.js +10 -2
  34. package/lib/deploy.js +26 -23
  35. package/lib/env/defaults.js +13 -6
  36. package/lib/env/index.js +73 -78
  37. package/lib/env/requires.js +38 -19
  38. package/lib/index.js +9 -10
  39. package/lib/lazy.js +2 -2
  40. package/lib/log/index.js +33 -45
  41. package/lib/log/service/index.js +2 -2
  42. package/lib/ql/CREATE.js +14 -9
  43. package/lib/ql/DELETE.js +6 -5
  44. package/lib/ql/DROP.js +12 -9
  45. package/lib/ql/INSERT.js +40 -16
  46. package/lib/ql/Query.js +67 -40
  47. package/lib/ql/SELECT.js +162 -127
  48. package/lib/ql/UPDATE.js +74 -42
  49. package/lib/ql/Whereable.js +77 -87
  50. package/lib/ql/index.js +36 -24
  51. package/lib/ql/parse.js +35 -0
  52. package/lib/req/context.js +44 -8
  53. package/lib/req/locale.js +7 -7
  54. package/lib/serve/Service-api.js +21 -14
  55. package/lib/serve/Service-dispatch.js +28 -12
  56. package/lib/serve/Transaction.js +22 -10
  57. package/lib/serve/index.js +16 -11
  58. package/lib/utils/axios.js +23 -16
  59. package/lib/utils/data.js +35 -0
  60. package/lib/utils/tests.js +27 -18
  61. package/libx/_runtime/audit/generic/personal/access.js +81 -0
  62. package/libx/_runtime/audit/generic/personal/constants.js +4 -0
  63. package/libx/_runtime/audit/generic/personal/index.js +50 -0
  64. package/libx/_runtime/audit/generic/personal/modification.js +138 -0
  65. package/libx/_runtime/audit/generic/personal/utils.js +186 -0
  66. package/libx/_runtime/audit/utils/v2.js +10 -4
  67. package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +5 -5
  68. package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +6 -7
  69. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +5 -7
  70. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +5 -7
  71. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/delete.js +2 -3
  72. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +4 -0
  73. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +7 -4
  74. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +59 -8
  75. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +11 -1
  76. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +6 -10
  77. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +3 -46
  78. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/applyToCQN.js +2 -5
  79. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/createToCQN.js +2 -2
  80. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/deleteToCQN.js +4 -3
  81. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/expandToCQN.js +1 -2
  82. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/index.js +0 -1
  83. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/selectHelper.js +1 -1
  84. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/updateToCQN.js +2 -2
  85. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/utils.js +16 -18
  86. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/edm/EdmEntityType.js +6 -3
  87. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/format/RepresentationKind.js +4 -1
  88. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/core/OdataRequest.js +1 -0
  89. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/SerializerFactory.js +15 -2
  90. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/validator/OperationValidator.js +1 -0
  91. package/libx/_runtime/cds-services/adapter/odata-v4/to.js +1 -1
  92. package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +8 -1
  93. package/libx/_runtime/cds-services/adapter/odata-v4/utils/handlerUtils.js +6 -1
  94. package/libx/_runtime/cds-services/adapter/odata-v4/utils/omitValues.js +12 -5
  95. package/libx/_runtime/cds-services/adapter/odata-v4/utils/readAfterWrite.js +1 -7
  96. package/libx/_runtime/cds-services/adapter/odata-v4/utils/request.js +7 -7
  97. package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +14 -18
  98. package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +13 -13
  99. package/libx/_runtime/cds-services/adapter/rest/handlers/create.js +0 -1
  100. package/libx/_runtime/cds-services/adapter/rest/handlers/operation.js +2 -1
  101. package/libx/_runtime/cds-services/adapter/rest/handlers/read.js +2 -2
  102. package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/index.js +2 -4
  103. package/libx/_runtime/cds-services/adapter/rest/utils/result.js +4 -2
  104. package/libx/_runtime/cds-services/services/Service.js +40 -5
  105. package/libx/_runtime/cds-services/services/utils/columns.js +13 -7
  106. package/libx/_runtime/cds-services/services/utils/compareJson.js +88 -4
  107. package/libx/_runtime/cds-services/services/utils/differ.js +24 -6
  108. package/libx/_runtime/cds-services/services/utils/handlerUtils.js +2 -2
  109. package/libx/_runtime/common/composition/data.js +66 -63
  110. package/libx/_runtime/common/composition/delete.js +97 -71
  111. package/libx/_runtime/common/composition/index.js +2 -1
  112. package/libx/_runtime/common/composition/insert.js +34 -11
  113. package/libx/_runtime/common/composition/tree.js +119 -92
  114. package/libx/_runtime/common/composition/update.js +12 -1
  115. package/libx/_runtime/common/composition/utils.js +1 -3
  116. package/libx/_runtime/common/constants/draft.js +12 -1
  117. package/libx/_runtime/common/generic/auth.js +53 -31
  118. package/libx/_runtime/common/generic/crud.js +14 -13
  119. package/libx/_runtime/common/generic/input.js +23 -26
  120. package/libx/_runtime/common/generic/put.js +1 -1
  121. package/libx/_runtime/common/generic/sorting.js +16 -16
  122. package/libx/_runtime/common/i18n/index.js +1 -1
  123. package/libx/_runtime/common/i18n/messages.properties +4 -0
  124. package/libx/_runtime/common/utils/backlinks.js +12 -5
  125. package/libx/_runtime/common/utils/cqn.js +6 -1
  126. package/libx/_runtime/common/utils/cqn2cqn4sql.js +123 -108
  127. package/libx/_runtime/common/utils/csn.js +56 -4
  128. package/libx/_runtime/common/utils/data.js +0 -37
  129. package/libx/_runtime/common/utils/enrichWithKeysFromWhere.js +1 -1
  130. package/libx/_runtime/common/utils/entityFromCqn.js +7 -24
  131. package/libx/_runtime/common/utils/foreignKeyPropagations.js +39 -7
  132. package/libx/_runtime/common/utils/generateOnCond.js +11 -12
  133. package/libx/_runtime/common/utils/onlyKeysRemain.js +10 -0
  134. package/libx/_runtime/common/utils/path.js +35 -0
  135. package/libx/_runtime/common/utils/postProcessing.js +86 -0
  136. package/libx/_runtime/common/utils/quotingStyles.js +37 -26
  137. package/libx/_runtime/common/utils/resolveView.js +227 -173
  138. package/libx/_runtime/common/utils/rewriteAsterisk.js +46 -26
  139. package/libx/_runtime/common/utils/structured.js +13 -13
  140. package/libx/_runtime/common/utils/template.js +10 -5
  141. package/libx/_runtime/common/utils/templateDelimiter.js +1 -0
  142. package/libx/_runtime/common/utils/templateProcessor.js +28 -72
  143. package/libx/_runtime/common/utils/union.js +31 -0
  144. package/libx/_runtime/common/utils/unionCqnTemplate.js +184 -0
  145. package/libx/_runtime/db/Service.js +1 -1
  146. package/libx/_runtime/db/data-conversion/timestamp.js +2 -9
  147. package/libx/_runtime/db/expand/expandCQNToJoin.js +204 -297
  148. package/libx/_runtime/db/expand/index.js +3 -3
  149. package/libx/_runtime/db/expand/rawToExpanded.js +36 -7
  150. package/libx/_runtime/db/generic/index.js +1 -1
  151. package/libx/_runtime/db/generic/input.js +5 -7
  152. package/libx/_runtime/db/generic/integrity.js +1 -1
  153. package/libx/_runtime/db/generic/rewrite.js +2 -10
  154. package/libx/_runtime/db/generic/update.js +13 -5
  155. package/libx/_runtime/db/generic/virtual.js +22 -58
  156. package/libx/_runtime/db/query/delete.js +7 -4
  157. package/libx/_runtime/db/query/insert.js +6 -4
  158. package/libx/_runtime/db/query/read.js +21 -8
  159. package/libx/_runtime/db/query/run.js +4 -1
  160. package/libx/_runtime/db/query/update.js +5 -4
  161. package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +35 -2
  162. package/libx/_runtime/db/sql-builder/FunctionBuilder.js +17 -2
  163. package/libx/_runtime/db/sql-builder/InsertBuilder.js +6 -5
  164. package/libx/_runtime/db/sql-builder/ReferenceBuilder.js +10 -0
  165. package/libx/_runtime/db/sql-builder/SelectBuilder.js +35 -24
  166. package/libx/_runtime/db/sql-builder/UpdateBuilder.js +14 -4
  167. package/libx/_runtime/db/sql-builder/arrayed.js +4 -0
  168. package/libx/_runtime/db/utils/deep.js +8 -0
  169. package/libx/_runtime/db/utils/generateAliases.js +2 -1
  170. package/libx/_runtime/fiori/generic/activate.js +19 -15
  171. package/libx/_runtime/fiori/generic/before.js +3 -11
  172. package/libx/_runtime/fiori/generic/cancel.js +1 -1
  173. package/libx/_runtime/fiori/generic/delete.js +3 -1
  174. package/libx/_runtime/fiori/generic/edit.js +12 -2
  175. package/libx/_runtime/fiori/generic/new.js +5 -5
  176. package/libx/_runtime/fiori/generic/patch.js +0 -18
  177. package/libx/_runtime/fiori/generic/read.js +261 -205
  178. package/libx/_runtime/fiori/utils/delete.js +36 -7
  179. package/libx/_runtime/fiori/utils/handler.js +43 -44
  180. package/libx/_runtime/fiori/utils/where.js +30 -15
  181. package/libx/_runtime/hana/customBuilder/CustomSelectBuilder.js +4 -6
  182. package/libx/_runtime/hana/execute.js +3 -3
  183. package/libx/_runtime/hana/localized.js +4 -4
  184. package/libx/_runtime/hana/pool.js +29 -14
  185. package/libx/_runtime/hana/search2cqn4sql.js +2 -1
  186. package/libx/_runtime/hana/searchToContains.js +18 -14
  187. package/libx/_runtime/index.js +0 -5
  188. package/libx/_runtime/messaging/AMQPWebhookMessaging.js +13 -5
  189. package/libx/_runtime/messaging/common-utils/naming-conventions.js +4 -1
  190. package/libx/_runtime/messaging/enterprise-messaging-utils/EMManagement.js +31 -19
  191. package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +1 -2
  192. package/libx/_runtime/messaging/enterprise-messaging.js +6 -4
  193. package/libx/_runtime/messaging/service.js +7 -6
  194. package/libx/_runtime/odata/cqn2odata.js +110 -43
  195. package/libx/_runtime/odata/index.js +26 -48
  196. package/libx/_runtime/odata/odata2cqn.js +1 -6154
  197. package/libx/_runtime/odata/odata2cqn.pegjs +559 -0
  198. package/libx/_runtime/odata/readToCqn.js +94 -64
  199. package/libx/_runtime/remote/Service.js +74 -21
  200. package/libx/_runtime/remote/cqn2odata/index.js +1 -5
  201. package/libx/_runtime/remote/utils/client.js +24 -101
  202. package/libx/_runtime/remote/utils/dataConversion.js +27 -12
  203. package/libx/_runtime/sqlite/Service.js +3 -5
  204. package/libx/_runtime/sqlite/execute.js +33 -27
  205. package/libx/_runtime/sqlite/localized.js +12 -7
  206. package/libx/_runtime/types/api.js +10 -0
  207. package/package.json +2 -2
  208. package/server.js +16 -2
  209. package/lib/ql/grammar.pegjs +0 -208
  210. package/lib/ql/parser.js +0 -1
  211. package/lib/ql/rt/DELETE.js +0 -29
  212. package/lib/ql/rt/INSERT.js +0 -23
  213. package/lib/ql/rt/Query.js +0 -84
  214. package/lib/ql/rt/SELECT.js +0 -174
  215. package/lib/ql/rt/UPDATE.js +0 -119
  216. package/lib/ql/rt/_helpers.js +0 -91
  217. package/lib/ql/rt/index.js +0 -32
  218. package/libx/_runtime/audit/generic/personal.js +0 -260
  219. package/libx/_runtime/cds-services/statements/BaseStatement.js +0 -72
  220. package/libx/_runtime/cds-services/statements/Create.js +0 -57
  221. package/libx/_runtime/cds-services/statements/Delete.js +0 -33
  222. package/libx/_runtime/cds-services/statements/Drop.js +0 -42
  223. package/libx/_runtime/cds-services/statements/Insert.js +0 -201
  224. package/libx/_runtime/cds-services/statements/Select.js +0 -826
  225. package/libx/_runtime/cds-services/statements/Update.js +0 -181
  226. package/libx/_runtime/cds-services/statements/Where.js +0 -726
  227. package/libx/_runtime/cds-services/statements/index.js +0 -25
  228. package/libx/_runtime/common/generic/resolve-mock.js +0 -9
package/CHANGELOG.md CHANGED
@@ -4,13 +4,249 @@
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.5.0 - 2021-09-23
8
+
9
+ ### Added
10
+
11
+ - Support for minified models
12
+ - Messaging: Webhooks use 'application/json' as the default content type
13
+ - Messaging: If senders don't use `data` as a property of the payload, then the whole payload is interpreted as `data`
14
+ - Messaging: Support for `$namespace` placeholer in queue name
15
+ - Support for deletable singletons with `@odata.singleton.nullable`
16
+ - Remote requests set the `accept-language` header according to the original request or the user's locale
17
+ - Support for choosing data source names different from names of respective service definitions.
18
+ + Example:
19
+ ```json
20
+ {"cds":{"requires":{
21
+ "S4": {
22
+ "model": "...", "service": "API_BUSINESS_PARTNER"
23
+ }
24
+ }}}
25
+ ```
26
+ - When calling `cds.tx()` to create new transactions, this now automatically inherits the current event context from `cds.context`. In case that creates issues set `cds.env.features.cds_tx_inheritance = false` to restore the former behaviour. You can still overwrite individual context settings, for example:
27
+ ```js
28
+ const tx = cds.tx() // inherits tenant and user
29
+ const tx = cds.tx({ // inherits tenant
30
+ user: new cds.User.Privileged
31
+ })
32
+ ```
33
+ - Method `cds.tx()` now allows to pass a function which will be executed within a new managed transaction, with `tx.commit/rollback()` handled automatically. For example:
34
+ ```js
35
+ await cds.tx (tx => {
36
+ await tx.insert (...)
37
+ await tx.read (...)
38
+ })
39
+ ```
40
+ is equivalent to:
41
+ ```js
42
+ const tx = cds.tx ()
43
+ try {
44
+ await tx.insert (...)
45
+ await tx.read (...)
46
+ await tx.commit()
47
+ } catch {
48
+ await tx.rollback()
49
+ }
50
+ ```
51
+ - Method `cds.tx({user})` now allows specifying a user as a plain string, for example:
52
+ ```js
53
+ cds.tx ({ user:'me' })
54
+ ```
55
+ is equivalent to:
56
+ ```js
57
+ cds.tx ({ user: new cds.User('me') })
58
+ ```
59
+ - Newly introduced method `cds.spawn()` allows correctly and conveniently spawning background jobs from within event handlers. Thereby ensuring a detached fully-managed ACID transaction set as `cds.context` for each execution of the background job, inheriting the current event context from the outer `cds.context` by default. Usage options:
60
+ ```js
61
+ cds.spawn (async ()=>{
62
+ await INSERT.into ('Ticker') ...
63
+ })
64
+ ```
65
+ ```js
66
+ cds.spawn (async ()=>{
67
+ await INSERT.into ('Ticker') ...
68
+ },{ after: 111 /* ms */ })
69
+ ```
70
+ ```js
71
+ let n=0, handle = cds.spawn (async ()=>{
72
+ await INSERT.into ('Ticker') ...
73
+ if (++n>9) clearTimeout (handle)
74
+ },{ every: 111 /* ms */ })
75
+ ```
76
+ ```js
77
+ cds.spawn (async ()=>{
78
+ await INSERT.into ('Ticker') ...
79
+ },{ // inherits tenant
80
+ every: 111 /* ms */,
81
+ user: new cds.User.Privileged
82
+ })
83
+ ```
84
+ - Default server is CORS-enabled for all origins if not in production
85
+ - Default lock acquire timeout for `SELECT FOR UPDATE` via `cds.env.sql.lock_acquire_timeout`
86
+ - Optimized search: Support `groupby` for localized data (when the environment variable `cds.env.features.optimized_search` is set to `true` on SAP HANA)
87
+ - Out-of-the-box audit logging for deep structures without own association to data subject
88
+ + limited to one data subject per role per composition tree
89
+ - Support for reading streams via `GET /<Entity>(<ID>)/$value`
90
+ - Draft choreography: support of navigation with `SiblingEntity`
91
+ - Support for where exists with infix filters in `@restrict`
92
+ - Support annotation `@Capabilities.ExpandRestrictions.NonExpandableProperties`
93
+ - `@Core.ContentID` added to OData error responses if `content-id` header is specified
94
+ - New OData URL to CQN parser (`cds.env.features.odata_new_parser`):
95
+ + support of navigation to primitive properties using `$value`
96
+ + support of `not` operator with string functions (`contains`, `startswith`, `endswith`)
97
+ - Support for default values for virtual fields
98
+ - Payload for non-writable navigation targets removed from `req.data`
99
+ - `cds build` supports i18n message bundles for Java and Nodejs apps and a default CSN format option for Java
100
+ - View resolving considers renaming of foreign keys and `excluding` names when `columns` are explicitly provided in CQN
101
+ - Resilient acquire for HANA via `cds.env.requires.db.connection_attempts = <number>` (alpha; hard max of 3 enforced)
102
+
103
+ ### Changed
104
+
105
+ - Messaging: Webhooks will always generate tokens
106
+ - Messaging: In multitenancy mode, messaging artifacts are only deployed to subscribers (unless the service option `deployForProvider` is set to `true`)
107
+ - Messaging: Incoming messages without corresponding handlers are not acknowledged
108
+ - 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.
109
+ + Deactivate during two month grace period via compact feature flag `cds.env.features.resolve_views = false`
110
+ - Use `@sap/cds-compiler`'s `smartId` function to determine whether a reference needs to be quoted.
111
+ + Allows the use of non-word characters in column names, for example `entity Foo { ![bar/bz]: String; }`.
112
+ + Support for columns with spaces with feature flag `cds.env.features.spaced_columns`.
113
+ + Note: Restrictions in other layers (example: OData's simple identifier schema) still apply.
114
+ + Note: Expressions in references (example: `ref: ['foo as bar']`) currently works but was never intended to and will be removed in future versions.
115
+ - Clear draft data based on their draft UUID instead of via deep delete
116
+ - Support `@sap/cds-compiler`'s changes for DB constraints: managed and unmanaged compositions of one behave like associations. This means that only `$self`-managed composition of one gets `DELETE CASCADE` constraint. Since all other "2one" cases require extra `DELETE` handled by the runtime, that constraint is ignored.
117
+ - Value with regards to date and time functions are not converted to strings in the OData protocol adapter
118
+ - No placeholders for `LIMIT` to enable statement caching during pagination
119
+ - Arrayed elements stringified in DB layer
120
+ - Return values of handlers will have precedence over database reads
121
+ - Error of a failed request to a Remote Service contains now the response payload if available
122
+ - Configuring ad-hoc destinations via `credentials.url` is now allowed in `NODE_ENV=production`
123
+ - New OData URL to CQN parser (`cds.env.features.odata_new_parser`):
124
+ + CQN for `$select` and `$expand` columns
125
+
126
+ ### Fixed
127
+
128
+ - `SELECT.from (Foo, f => f.bar('*').where(...))` resulted in a runtime exception
129
+ - Preserved locales are now considered when accessing database tables
130
+ - Integrity checks for compositions by draft enabled entities
131
+ - Constant columns must not be quoted anymore, i.e. `{ val: "'myValue'", as: "myColumn"}` must be changed to `{ val: "myValue", as: "myColumn" }`
132
+ - Accidental `tx.run()` after prior `tx.commit/rollback()` lead to acquired connections not returned to pool. This is detected and disallowed now. In case that creates issues set `cds.env.features.cds_tx_protection = false` to restore the former behaviour.
133
+ - Structured keys are correctly resolved with pegjs-based parser
134
+ - Template processing for columns with spaces in their name
135
+ - Deep delete with recursions in composition tree (with limited recursion depth)
136
+ - Draft edit with recursions in composition tree (with limited recursion depth)
137
+ - `emit` for messaging services now also works in custom express middlewares
138
+ - `req.query` is a CQN object (previously array with one entry) in case of batch insert in REST adapter
139
+ - HasActiveEntity flag with expand
140
+ - `compile.to.serviceinfo` now honors default Java endpoint paths if none are configured in `application.yaml`
141
+ - `PATCH` request to a non-existent entity annotated with the `@PersonalData` annotation
142
+ - `req.diff()` while deep updating via composition
143
+ - Convert data type of elements in sub-entities (to one association) when forwarding responses to external services
144
+ - Update children of a composition of many (`INSERT > DELETE`) with `PATCH/PUT` having at the same time another association to one composition child respects foreign key constraints.
145
+ - Handling of virtual fields used in the `$filter` query option of navigation requests
146
+ - Copy texts in default language from active to draft table on draft edit
147
+ - Optimized search: Escape double quotation marks and backslashes (when the environment variable `cds.env.features.optimized_search` is set to `true`)
148
+ - Update for multiple rows
149
+ - Expand during draft union
150
+ - Validate content type for `$batch` requests
151
+ - Support for `SELECT` statements in `where` clauses when resolving views
152
+ - `INSERT.rows()` does not silently fill in `INSERT.entries` anymore &rarr; use `INSERT.entries()` to do so instead.
153
+ - `UPDATE(Foo).with({foo:{'=':'bar'})` erroneously produced:
154
+ ```js
155
+ {UPDATE:{..., with:{foo:{ref:['bar']}}}} //> wrong
156
+ ```
157
+ instead of:
158
+ ```js
159
+ {UPDATE:{..., data:{foo:'bar'}}} // correct
160
+ ```
161
+ &rarr; to produce the ref, use one of:
162
+ ```js
163
+ UPDATE(Foo).with ({foo:{ref:['bar']}})
164
+ UPDATE(Foo).with `foo=bar`
165
+ ```
166
+ - `UPDATE.with` property stays undefined until actually filled with data
167
+ - Differentiate between require and initialize error of audit logging client
168
+ - The built-in model tree-shaking erroneously deleted explicitly modeled `.texts` entities
169
+ - Actions and functions with `Integer` response type in REST services
170
+ - Occasional drop of conditions in `WHERE` depending on the value when using structured types
171
+ - `PATCH` fixed for singletons and when having a keyless, for example, managed to-one navigation path
172
+ - Internal server error when forwarding a query to an external service whose target entity does not contain keys
173
+ - Nested where exists in `@restrict` via navigation (CRUD-only; beta)
174
+ - Expand to one in draft union
175
+ - Patch to autoexposed entity through composition of aspect from Fiori Elements
176
+ - Diff for delete in draft
177
+ - Streaming requests on views with joins no longer crash the application
178
+
179
+ ### Removed
180
+
181
+ - Direct usage of body-parser
182
+ - Queries constructed from `cds.ql` do not have the _internal_ property `cqn` anymore
183
+ - Inofficial variant `SELECT({'expand(foo)':['a','b']})` is not supported anymore
184
+ &rarr; use one of these official APIs for expands instead:
185
+ ```js
186
+ SELECT(x => { x.a, x.foo (f =>{ f.b, f.c }) })
187
+ SELECT(['a',{ref:['foo'], expand:['b','c']}])
188
+ ```
189
+ - Inofficial variant `SELECT.orderBy('foo','desc')` is not supported anymore
190
+ &rarr; use one of these official APIs instead:
191
+ ```js
192
+ SELECT.from(Foo).orderBy({foo:'desc'})
193
+ SELECT.from(Foo).orderBy('foo desc')
194
+ ```
195
+ - Inofficial variant `SELECT.orderBy('foo, bar desc')` is not supported anymore
196
+ &rarr; use one of these official APIs instead:
197
+ ```js
198
+ SELECT.from(Foo).orderBy({foo:1,bar:-1})
199
+ SELECT.from(Foo).orderBy('foo','bar desc')
200
+ SELECT.from(Foo).orderBy `foo, bar desc`
201
+ ```
202
+ - Inofficial variant `SELECT.where({ or: [{ foo: 'bar' }, { foo: 'baz' }] })` is not supported anymore
203
+ &rarr; use one of these official APIs instead:
204
+ ```js
205
+ SELECT.from(Foo).where({ foo: 'bar', or: { foo: 'baz' } })
206
+ SELECT.from(Foo).where `foo='bar' or foo='baz'`
207
+ ```
208
+ - Usage of SQL window functions during expand on HANA
209
+ - Hidden symbol for where clause elements originating from `@restrict`
210
+ - Error masking gate keeper for `cds.env.log.levels.cli`
211
+
212
+ ## Version 5.4.6 - 2021-09-18
213
+
214
+ ### Added
215
+
216
+ - Support for nested where exists in `@restrict` (CRUD-only; beta)
217
+
218
+ ### Fixed
219
+
220
+ - Inverse transition mapping calculation
221
+ - Skip empty structures during deep update
222
+
223
+ ## Version 5.4.5 - 2021-09-15
224
+
225
+ ### Fixed
226
+
227
+ - Processing of null elements during deep update
228
+ - Performance issue during template processing
229
+
230
+ ## Version 5.4.4 - 2021-09-09
231
+
232
+ ### Fixed
233
+
234
+ - For drafts, the query parameter `$top=0` in combination with `$count=true` now returns the correct `@odata.count` value
235
+ - Deep delete with composition of one with structured key in target
236
+ - Implicit delete of child with structured key
237
+ - Update of deeply nested entity with structured key
238
+ - Order by join column during draft union
239
+ - Skip calculated properties while following projections
240
+ - The `with parameters` clause is now correctly handled in sub selects if the locale parameter exceeds 3 characters
241
+ - Statement already finalized error on SQLite
242
+
7
243
  ## Version 5.4.3 - 2021-08-16
8
244
 
9
245
  ### Fixed
10
246
 
11
247
  - Skip calculated properties while following projections
12
- - Safe access to `cds.env.log.levels.cli`
13
248
  - Unrestricted subclauses in `@restrict.where`
249
+ - Safe access to `cds.env.log.levels.cli`
14
250
 
15
251
  ## Version 5.4.2 - 2021-08-11
16
252
 
@@ -50,6 +286,7 @@
50
286
  - Messaging: No more topic manipulation per default
51
287
  - For consistency reasons `cds build` now determines the default model path using cds resolve
52
288
  - Match XSUAA's user attribute value `$UNRESTRICTED` case insensitive
289
+ - CDS build now uses new CDS logging facade to allow for consistent logging behaviour accross the different CDS modules
53
290
 
54
291
  ### Fixed
55
292
 
@@ -63,7 +300,7 @@
63
300
  - Expand to autoexposed association/composition in draft case
64
301
  - `cds.parse.xpr()` always returns an array
65
302
  - Allow boolean options in `cds build` CLI
66
- - Integrity check in case of bulk query execution
303
+ - Integrity check in case of bulk query execution
67
304
 
68
305
  ### Removed
69
306
 
package/apis/ql.d.ts CHANGED
@@ -28,16 +28,9 @@ declare class QL {
28
28
  // (new QL).SELECT.from('Foo').byKey(11).a
29
29
 
30
30
  export class SELECT<T> extends ConstructedQuery {
31
+ static one : SELECT_one & { from: SELECT_one }
31
32
  static distinct : typeof SELECT
32
- static one : typeof SELECT_one
33
- static from (entity: Definition | string, primaryKey? : number | string | object, projection? : (e:any)=>void) : SELECT<any>
34
- static from <T> (entity:Constructable<T>, primaryKey : number | string | object, projection? : (e:T)=>void) : SELECT<T> & Promise<T>
35
- static from <T> (entity:Constructable<T>, projection? : (e:T)=>void) : SELECT<T> & Promise<T[]>
36
- static from <T> (entity:Constructable<T>, primaryKey : number | string | object, projection? : (e:T)=>void) : SELECT<T> & Promise<T>
37
- static from <T> (entity:T[], projection? : (e:T)=>void) : SELECT<T> & Promise<T[]>
38
- static from <T> (entity:T, projection? : (e:T)=>void) : SELECT<T> & Promise<T[]>
39
- static from <T> (entity:T[], primaryKey : number | string | object, projection? : (e:T)=>void) : SELECT<T> & Promise<T>
40
- static from <T> (entity:T, primaryKey : number | string | object, projection? : (e:T)=>void) : SELECT<T> & Promise<T>
33
+ static from : SELECT_from
41
34
  from (entity: Definition | string, primaryKey? : number | string | object, projection? : (e:any)=>void) : this
42
35
  byKey (primaryKey? : number | string | object) : this
43
36
  columns (projection:(e:T)=>void) : this
@@ -54,12 +47,21 @@ export class SELECT<T> extends ConstructedQuery {
54
47
  SELECT : CQN.SELECT
55
48
  }
56
49
 
57
- export class SELECT_one<T> extends SELECT<T> {
58
- static from <T> (entity:Constructable<T>, projection? : (e:T)=>void) : SELECT<T> & Promise<T>
59
- static from <T> (entity:Constructable<T>, primaryKey? : number | string | object, projection? : (e:T)=>void) : SELECT<T> & Promise<T>
60
- static from (entity: Definition | string, primaryKey? : number | string | object, projection? : (e:any)=>void) : SELECT<any>
61
- static from <T> (entity:T, primaryKey? : number | string | object, projection? : (e:T)=>void) : SELECT<T> & Promise<T>
62
- }
50
+ type SELECT_one =
51
+ ((entity: Definition | string, primaryKey? : number | string | object, projection? : (e:any)=>void) => SELECT<any>)
52
+ & (<T> (entity: T[], projection? : (e:T)=>void) => SELECT<T> & Promise<T>)
53
+ & (<T> (entity: T[], primaryKey : number | string | object, projection? : (e:T)=>void) => SELECT<T> & Promise<T>)
54
+ & (<T> (entity: {new():T}, projection? : (e:T)=>void) => SELECT<T> & Promise<T>)
55
+ & (<T> (entity: {new():T}, primaryKey : number | string | object, projection? : (e:T)=>void) => SELECT<T> & Promise<T>)
56
+
57
+
58
+ type SELECT_from =
59
+ ((entity: Definition | string, primaryKey? : number | string | object, projection? : (e:any)=>void) => SELECT<any>)
60
+ & (<T> (entity: T[], projection? : (e:T)=>void) => SELECT<T> & Promise<T[]>)
61
+ & (<T> (entity: T[], primaryKey : number | string | object, projection? : (e:T)=>void) => SELECT<T> & Promise<T>)
62
+ & (<T> (entity: {new():T}, projection? : (e:T)=>void) => SELECT<T> & Promise<T[]>)
63
+ & (<T> (entity: {new():T}, primaryKey : number | string | object, projection? : (e:T)=>void) => SELECT<T> & Promise<T>)
64
+
63
65
 
64
66
  export class INSERT<T> extends ConstructedQuery {
65
67
  static into (entity : Definition | string, entries? : object | object[]) : INSERT<any>
package/app/index.js CHANGED
@@ -21,7 +21,7 @@ module.exports = { get html(){
21
21
  <ul>${_entities_in(srv).map (e => {
22
22
  return `
23
23
  <li>
24
- <a href="${srv.path}/${e.replace(/\./g, '_')}?$top=11">${e}</a> ${_moreLinks(srv, e)}
24
+ <a href="${srv.path}/${e.replace(/\./g, '_')}">${e}</a> ${_moreLinks(srv, e)}
25
25
  </li>`}).join('')}
26
26
  </ul>
27
27
  `) .join(''))
@@ -4,17 +4,16 @@ const _cds = require('./cds'), { log } = _cds.exec
4
4
  const BuildTaskProviderFactory = require('./buildTaskProviderFactory')
5
5
  const { sortMessagesSeverityAware, deduplicateMessages, CompilationError } = require('@sap/cds-compiler')
6
6
  const { allSettled, relativePaths, BuildError, BuildMessage } = require('./util')
7
- const { OUTPUT_MODE_DEFAULT, SEVERITIES, LOG_LEVELS } = require('./constants')
7
+ const { OUTPUT_MODE_DEFAULT, SEVERITIES, LOG_LEVELS, LOG_MODULE_NAMES } = require('./constants')
8
8
  const BuildTaskHandlerInternal = require('./provider/buildTaskHandlerInternal')
9
9
 
10
- const DEBUG = process.env.DEBUG
11
10
  const COMPILATION_ERROR = 'CompilationError'
12
11
  const COMPILE_MESSAGE = 'CompileMessage'
13
12
 
14
13
  class BuildTaskEngine {
15
14
  constructor(logger, cds) {
16
- this._logger = logger || global.console
17
15
  this._cds = cds ? cds : _cds
16
+ this._logger = logger || this._cds.log(LOG_MODULE_NAMES)
18
17
  }
19
18
 
20
19
  get cds() {
@@ -29,8 +28,7 @@ class BuildTaskEngine {
29
28
 
30
29
  async processTasks(tasks, buildOptions, clean = true) {
31
30
  const handlers = []
32
- const timerKey = "[cds] - build completed in"
33
- this.logger.time(timerKey)
31
+ const startTime = Date.now()
34
32
 
35
33
  if (buildOptions) {
36
34
  // clone as data may be stored as part of the buildOptions object
@@ -44,8 +42,8 @@ class BuildTaskEngine {
44
42
  buildOptions.outputMode = OUTPUT_MODE_DEFAULT
45
43
  }
46
44
 
47
- this.logger.log(`[cds] - building project [${buildOptions.root}], clean [${clean}]`)
48
- this.logger.log(`[cds] - cds [${_cds.version}], compiler [${require('@sap/cds-compiler/package.json').version}], home [${_cds.home}]\n`)
45
+ this.logger.log(`building project [${buildOptions.root}], clean [${clean}]`)
46
+ this.logger.log(`cds [${_cds.version}], compiler [${require('@sap/cds-compiler/package.json').version}], home [${_cds.home}]\n`)
49
47
 
50
48
  if (!buildOptions.target) {
51
49
  buildOptions.target = path.resolve(buildOptions.root, this.env.build.target)
@@ -62,12 +60,12 @@ class BuildTaskEngine {
62
60
  buildOptions.tasks = handlers.map(handler => handler.task)
63
61
 
64
62
  try {
65
- await this._executePrepare(handlers)
63
+ await this._executePrepare(handlers, buildOptions)
66
64
  await this._executeCleanBuildTasks(handlers, buildOptions, clean)
67
65
  const buildResult = await this._executeBuildTasks(handlers, buildOptions)
68
66
  await this._logBuildOutput(handlers, buildOptions)
69
67
  this._logMessages(buildOptions, BuildTaskEngine._getHandlerMessages(handlers))
70
- this._logTimer(timerKey)
68
+ this._logTimer(startTime, Date.now())
71
69
 
72
70
  return buildResult
73
71
  } catch (error) {
@@ -93,7 +91,7 @@ class BuildTaskEngine {
93
91
  * @param {*} handlers
94
92
  * @returns
95
93
  */
96
- async _executePrepare(handlers) {
94
+ async _executePrepare(handlers, buildOptions) {
97
95
  const handlerGroups = new Map()
98
96
 
99
97
  // group handlers by type
@@ -103,7 +101,7 @@ class BuildTaskEngine {
103
101
 
104
102
  const promises = []
105
103
  for (let handlerGroup of handlerGroups.values()) {
106
- promises.push(this._doPrepare(handlerGroup))
104
+ promises.push(this._doPrepare(handlerGroup, buildOptions))
107
105
  }
108
106
  return Promise.all(promises)
109
107
  }
@@ -112,13 +110,11 @@ class BuildTaskEngine {
112
110
  * @deprecated
113
111
  * @param {*} handlerGroup
114
112
  */
115
- async _doPrepare(handlerGroup) {
113
+ async _doPrepare(handlerGroup, buildOptions) {
116
114
  for (let handler of handlerGroup) {
117
115
  // prepare has been deprecated
118
116
  if (handler instanceof BuildTaskHandlerInternal) {
119
- if (DEBUG) {
120
- this.logger.log(`[cds] - preparing, handler [${handler.constructor.name}], src [${relativePaths(handler.buildOptions.root, handler.task.src)}]`)
121
- }
117
+ this.logger._debug && this.logger.debug(`preparing, handler [${handler.constructor.name}], src [${relativePaths(buildOptions.root, handler.task.src)}]`)
122
118
  const result = await handler.prepare()
123
119
  if (result === false) {
124
120
  break
@@ -131,16 +127,12 @@ class BuildTaskEngine {
131
127
  if (clean) {
132
128
  // clean entire build staging folder once
133
129
  if (buildOptions.target !== buildOptions.root) {
134
- if (DEBUG) {
135
- this.logger.log(`[cds] - cleaning staging folder ${buildOptions.target}`)
136
- }
130
+ this.logger._debug && this.logger.debug(`cleaning staging folder ${buildOptions.target}`)
137
131
  await fs.remove(buildOptions.target)
138
132
  }
139
133
 
140
134
  const results = await allSettled(handlers.map((handler) => {
141
- if (DEBUG) {
142
- this.logger.log(`[cds] - cleaning, handler [${handler.constructor.name}], src [${relativePaths(handler.buildOptions.root, handler.task.src)}]`)
143
- }
135
+ this.logger._debug && this.logger.debug(`cleaning, handler [${handler.constructor.name}], src [${relativePaths(buildOptions.root, handler.task.src)}]`)
144
136
  return handler.clean()
145
137
  }))
146
138
  // check for errors and throw exception
@@ -178,9 +170,7 @@ class BuildTaskEngine {
178
170
  let allResults = []
179
171
  for (const group of pipeline) {
180
172
  const results = await allSettled(group.map((handler) => {
181
- if (DEBUG) {
182
- this.logger.log(`[cds] - building, handler [${handler.constructor.name}], src [${relativePaths(handler.buildOptions.root, handler.task.src)}]`)
183
- }
173
+ this.logger._debug && this.logger.debug(`building, handler [${handler.constructor.name}], src [${relativePaths(buildOptions.root, handler.task.src)}]`)
184
174
  return handler.build()
185
175
  .then(handlerResult => {
186
176
  return Promise.resolve({
@@ -245,9 +235,8 @@ class BuildTaskEngine {
245
235
  // that generated content cannot be overwriten by mistake
246
236
  throw new Error(`Illegal priority for ${handler.consructor.name} encountered for custom handler - in this version only priority value '1' is allowed`)
247
237
  }
248
- if (DEBUG) {
249
- this._logTaskHandler(handler)
250
- }
238
+ this._logTaskHandler(handler, buildOptions)
239
+
251
240
  return handler
252
241
  } catch (error) {
253
242
  log(error, { log: this.logger.log })
@@ -263,38 +252,33 @@ class BuildTaskEngine {
263
252
  async _logBuildOutput(handlers, buildOptions, writeOutputFile = true) {
264
253
  // log all generated files
265
254
  const files = this._getBuildOutput(handlers, buildOptions)
266
-
267
255
  if (files.length > 0) {
268
- this.logger.log('\n[cds] - done > wrote output to:')
269
- files.forEach((file) => {
270
- this.logger.log(' ' + file)
271
- })
256
+ this.logger.log(`done > wrote output to:\n ${files.join("\n ")}\n`)
257
+ } else {
258
+ this.logger.log('done >')
272
259
  }
273
260
 
274
261
  if (writeOutputFile) {
275
262
  const outputFile = this.env.build.outputfile || process.env.GENERATION_LOG
276
263
  if (outputFile) {
277
- this.logger.log(`[cds] - writing generation log to [${outputFile}]`)
264
+ this.logger.log(`writing generation log to [${outputFile}]\n`)
278
265
  await fs.outputFile(outputFile, files.join('\n'))
279
266
  .catch((error) => {
280
- this.logger.error(`[cds] - failed to write generation log`)
267
+ this.logger.error(`failed to write generation log`)
281
268
  this.logger.error(error.stack || error)
282
269
  return Promise.resolve()
283
270
  })
284
271
  }
285
272
  }
286
- this.logger.log('')
287
273
  }
288
274
 
289
- _logTimer(timerKey) {
290
- this.logger.log('')
291
- this.logger.timeEnd(timerKey)
292
- this.logger.log('')
275
+ _logTimer(start, end) {
276
+ this.logger.log(`build completed in ${end - start} ms\n`)
293
277
  }
294
278
 
295
- _logTaskHandler(handler) {
296
- this.logger.log(`[cds] - handler ${handler.constructor.name}`)
297
- this.logger.log(`[cds] - details src [${relativePaths(handler.buildOptions.root, handler.task.src)}], dest [${relativePaths(handler.buildOptions.root, handler.task.dest)}], for|use [${handler.for | handler.task.use}], options [${JSON.stringify(handler.task.options)}]`) //NOSONAR
279
+ _logTaskHandler(handler, buildOptions) {
280
+ this.logger._debug && this.logger.debug(`handler ${handler.constructor.name}`)
281
+ this.logger._debug && this.logger.debug(`details src [${relativePaths(buildOptions.root, handler.task.src)}], dest [${relativePaths(buildOptions.root, handler.task.dest)}], use [${handler.task.use}], options [${JSON.stringify(handler.task.options)}]`) //NOSONAR
298
282
  }
299
283
 
300
284
  _logMessages(buildOptions, messages) {
@@ -3,14 +3,12 @@ const path = require('path')
3
3
  const _cds = require('./cds'), { log } = _cds.exec
4
4
  const BuildTaskProviderFactory = require('./buildTaskProviderFactory')
5
5
  const { hasJavaNature, getProperty, redactCredentials } = require('./util')
6
- const { FILE_EXT_CDS, BUILD_TASK_JAVA } = require("./constants")
7
-
8
- const DEBUG = process.env.DEBUG
6
+ const { FILE_EXT_CDS, BUILD_TASK_JAVA, LOG_MODULE_NAMES } = require("./constants")
9
7
 
10
8
  class BuildTaskFactory {
11
9
  constructor(logger, cds) {
12
- this._logger = logger || global.console
13
10
  this._cds = cds ? cds : _cds
11
+ this._logger = logger || this._cds.log(LOG_MODULE_NAMES)
14
12
  }
15
13
  get cds() {
16
14
  return this._cds
@@ -42,10 +40,8 @@ class BuildTaskFactory {
42
40
  this.logger.log(tasksOutput)
43
41
 
44
42
  // for testing purposes
45
- if (process.env.DEBUG) {
46
- this.logger.log("[cds] - cds.env used for build:")
47
- this.logger.log(redactCredentials(this.env))
48
- }
43
+ this.logger.debug("cds.env used for build:")
44
+ this.logger._debug && this.logger.debug(redactCredentials(this.env))
49
45
 
50
46
  // always resolve tasks for input validation
51
47
  if (buildOptions.resolve || buildOptions.cli) {
@@ -121,8 +117,8 @@ class BuildTaskFactory {
121
117
  const srv = task ? task.src : BuildTaskFactory._getModuleFolder(buildOptions.root, BuildTaskFactory._flatten([this.env.folders.srv])) || "srv"
122
118
 
123
119
  // Java projects use "." as the default build target folder
124
- if (this._hasJavaNature(buildOptions.root, srv) && this._adaptBuildTargetSettingForJava(buildOptions.root) && DEBUG) {
125
- this.logger.log("[cds] - using inplace build for java project instead of default staging build")
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")
126
122
  }
127
123
  buildOptions.target = path.resolve(buildOptions.root, this.env.build.target)
128
124
  }
@@ -179,12 +179,10 @@ class BuildTaskHandler {
179
179
  async model() {
180
180
  const files = this._resolveModel()
181
181
  if (!files || files.length === 0) {
182
- this._logger.log("[cds] - no model found, skip build")
182
+ this._logger.log("no model found, skip build")
183
183
  return null
184
184
  }
185
- if (process.env.DEBUG) {
186
- this._logger.log(`[cds] - model: ${relativePaths(this._buildOptions.root, files).join(", ")}`)
187
- }
185
+ this._logger._debug && this._logger.debug(`model: ${relativePaths(this._buildOptions.root, files).join(", ")}`)
188
186
  const options = { messages: this._messages }
189
187
  // $location paths are relative to current working dir by default - make sure a given project root folder is taken
190
188
  options.cwd = this._buildOptions.root
@@ -17,6 +17,8 @@ module.exports = class BuildTaskProvider {
17
17
  // task.for = task.for || this._getTaskId(task.use)
18
18
  }
19
19
  _getTaskId(use) {
20
- return use.substring(this._plugin.id.length + 1)
20
+ if (this._plugin && this._plugin.id) {
21
+ return use.substring(this._plugin.id.length + 1)
22
+ }
21
23
  }
22
24
  }
@@ -1,16 +1,14 @@
1
1
  const { fs } = require('@sap/cds-foss')
2
2
  const path = require('path')
3
3
  const _cds = require('./cds')
4
- const { OUTPUT_MODE_DEFAULT } = require("./constants")
4
+ const { OUTPUT_MODE_DEFAULT, LOG_MODULE_NAMES } = require("./constants")
5
5
  const BuildTaskProviderInternal = require('./provider/buildTaskProviderInternal')
6
6
  const BuildTaskProvider = require('./buildTaskProvider')
7
7
 
8
- const DEBUG = process.env.DEBUG
9
-
10
8
  class BuildTaskProviderFactory {
11
9
  constructor(logger, cds, buildOptions) {
12
10
  this._cds = cds ? cds : _cds
13
- this._logger = logger || global.console
11
+ this._logger = logger || this._cds.log(LOG_MODULE_NAMES)
14
12
  buildOptions.for = buildOptions.for || {}
15
13
  buildOptions.outputMode = buildOptions.outputMode || OUTPUT_MODE_DEFAULT
16
14
  this._buildOptions = buildOptions
@@ -50,14 +48,15 @@ class BuildTaskProviderFactory {
50
48
  if (!provider) {
51
49
  throw new Error(`No provider found for build task '${task.for || task.use}'`)
52
50
  }
51
+ if (provider instanceof DefaultBuildTaskProvider) {
52
+ this.logger._debug && this.logger.debug(`No provider found for build task '${task.use}', using default provider`)
53
+ }
53
54
  await this._applyTaskDefaults(provider, [task])
54
55
  }))
55
56
  }
56
57
 
57
58
  async lookupTasks() {
58
- if (DEBUG) {
59
- this.logger.log("[cds] - Determining CDS build tasks from CDS configuration - applying defaults")
60
- }
59
+ this.logger.debug("[cds] - Determining CDS build tasks from CDS configuration - applying defaults")
61
60
  let tasks = []
62
61
  await Promise.all(this.providers.map(async (provider) => {
63
62
  let pluginTasks = await this._lookupTasks(provider)
@@ -68,7 +67,7 @@ class BuildTaskProviderFactory {
68
67
  await this._applyTaskDefaults(provider, pluginTasks)
69
68
 
70
69
  tasks = tasks.concat(pluginTasks)
71
- this.logger.debug(`Build task provider ${provider.constructor.name} returned build tasks ${JSON.stringify(pluginTasks)}`)
70
+ this.logger._debug && this.logger.debug(`Build task provider ${provider.constructor.name} returned build tasks ${JSON.stringify(pluginTasks)}`)
72
71
  }))
73
72
  return tasks
74
73
  }
@@ -82,19 +81,14 @@ class BuildTaskProviderFactory {
82
81
  createHandler(task) {
83
82
  const BuildTaskHandlerClass = this.loadHandler(task)
84
83
  const resolvedTask = this.resolveTask(task)
85
- if (DEBUG) {
86
- this.logger.log(`[cds] - loaded build task handler [${resolvedTask.use}]`)
87
- }
84
+ this.logger._debug && this.logger.debug(`[cds] - loaded build task handler [${resolvedTask.use}]`)
88
85
 
89
86
  const handler = new BuildTaskHandlerClass()
90
87
  handler._task = resolvedTask
91
88
  handler._cds = this.cds
92
89
  handler._logger = this.logger
93
90
  handler._buildOptions = this.buildOptions
94
-
95
- if (DEBUG) {
96
- this.logger.log(`[cds] - created BuildTaskHandler [${resolvedTask.use}]`)
97
- }
91
+ this.logger._debug && this.logger.debug(`[cds] - created BuildTaskHandler [${resolvedTask.use}]`)
98
92
  return handler
99
93
  }
100
94