@sap/cds 6.1.3 → 6.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. package/CHANGELOG.md +83 -8
  2. package/apis/cds.d.ts +18 -6
  3. package/apis/connect.d.ts +1 -1
  4. package/apis/cqn.d.ts +1 -1
  5. package/apis/log.d.ts +23 -5
  6. package/apis/ql.d.ts +128 -61
  7. package/apis/services.d.ts +11 -0
  8. package/apis/test.d.ts +61 -0
  9. package/apis/utils.d.ts +15 -0
  10. package/app/fiori/preview.js +1 -0
  11. package/bin/build/buildTaskEngine.js +70 -22
  12. package/bin/build/buildTaskFactory.js +18 -11
  13. package/bin/build/buildTaskHandler.js +1 -1
  14. package/bin/build/buildTaskProviderFactory.js +3 -13
  15. package/bin/build/constants.js +0 -1
  16. package/bin/build/index.js +14 -6
  17. package/bin/build/provider/buildTaskHandlerEdmx.js +2 -3
  18. package/bin/build/provider/buildTaskHandlerFeatureToggles.js +2 -2
  19. package/bin/build/provider/buildTaskHandlerInternal.js +3 -6
  20. package/bin/build/provider/buildTaskProviderInternal.js +51 -39
  21. package/bin/build/provider/fiori/index.js +3 -3
  22. package/bin/build/provider/hana/2migration.js +1 -1
  23. package/bin/build/provider/hana/index.js +34 -27
  24. package/bin/build/provider/java/index.js +6 -7
  25. package/bin/build/provider/mtx/index.js +20 -18
  26. package/bin/build/provider/mtx/resourcesTarBuilder.js +8 -11
  27. package/bin/build/provider/mtx-sidecar/index.js +13 -17
  28. package/bin/build/provider/nodejs/index.js +8 -7
  29. package/bin/build/util.js +22 -4
  30. package/bin/cds.js +8 -4
  31. package/bin/deploy/to-hana/cfUtil.js +53 -18
  32. package/bin/mtx/in-cds.js +1 -0
  33. package/bin/serve.js +37 -30
  34. package/lib/auth/basic-auth.js +33 -0
  35. package/lib/auth/dummy-auth.js +7 -0
  36. package/lib/auth/ias-auth.js +2 -0
  37. package/lib/auth/index.js +31 -0
  38. package/lib/auth/jwt-auth.js +3 -0
  39. package/lib/auth/mocked-users.js +72 -0
  40. package/lib/auth/passport-basic.js +12 -0
  41. package/lib/auth/passport-digest.js +14 -0
  42. package/lib/auth/xsuaa-auth.js +3 -0
  43. package/lib/compile/cds-compile.js +3 -3
  44. package/lib/compile/to/cdl.js +5 -1
  45. package/lib/compile/to/edm.js +8 -0
  46. package/lib/compile/to/gql.js +1 -0
  47. package/lib/compile/to/json.js +30 -5
  48. package/lib/compile/to/sql.js +3 -1
  49. package/lib/core/index.js +5 -1
  50. package/lib/dbs/cds-deploy.js +36 -6
  51. package/lib/env/cds-env.js +15 -5
  52. package/lib/env/cds-requires.js +51 -58
  53. package/lib/env/defaults.js +1 -0
  54. package/lib/env/schemas/cds-package.json +4 -0
  55. package/lib/env/schemas/cds-rc.json +63 -77
  56. package/lib/i18n/localize.js +16 -5
  57. package/lib/index.js +9 -4
  58. package/lib/log/cds-error.js +4 -6
  59. package/lib/log/cds-log.js +89 -53
  60. package/lib/log/service/index.js +1 -0
  61. package/lib/ql/CREATE.js +2 -5
  62. package/lib/ql/DELETE.js +1 -1
  63. package/lib/ql/DROP.js +1 -3
  64. package/lib/ql/INSERT.js +3 -3
  65. package/lib/ql/Query.js +10 -23
  66. package/lib/ql/SELECT.js +1 -2
  67. package/lib/ql/UPDATE.js +2 -2
  68. package/lib/ql/Whereable.js +7 -15
  69. package/lib/ql/cds-ql.js +9 -3
  70. package/lib/req/cds-context.js +11 -3
  71. package/lib/req/context.js +29 -23
  72. package/lib/req/locale.js +9 -5
  73. package/lib/req/request.js +1 -0
  74. package/lib/req/user.js +2 -1
  75. package/lib/srv/cds-connect.js +1 -1
  76. package/lib/srv/cds-serve.js +21 -14
  77. package/lib/srv/middlewares/cds-context.js +29 -0
  78. package/lib/srv/middlewares/ctx-model.js +24 -0
  79. package/lib/srv/middlewares/errors.js +9 -0
  80. package/lib/srv/middlewares/index.js +22 -0
  81. package/lib/srv/middlewares/sap-statistics.js +13 -0
  82. package/lib/srv/middlewares/trace.js +102 -0
  83. package/lib/srv/protocols/_legacy.js +42 -0
  84. package/lib/srv/protocols/graphql.js +39 -0
  85. package/lib/srv/protocols/hcql.js +37 -0
  86. package/lib/srv/protocols/index.js +86 -0
  87. package/lib/srv/protocols/odata-v2-proxy.js +3767 -0
  88. package/lib/srv/protocols/odata-v2.js +26 -0
  89. package/lib/srv/protocols/odata-v4.js +16 -0
  90. package/lib/srv/protocols/rest.js +13 -0
  91. package/lib/srv/srv-api.js +5 -0
  92. package/lib/srv/srv-models.js +4 -6
  93. package/lib/utils/axios.js +3 -2
  94. package/lib/utils/cds-test.js +27 -21
  95. package/lib/utils/cds-utils.js +19 -20
  96. package/lib/utils/tar.js +175 -0
  97. package/libx/_runtime/audit/generic/personal/utils.js +18 -7
  98. package/libx/_runtime/audit/utils/v2.js +1 -0
  99. package/libx/_runtime/auth/index.js +4 -0
  100. package/libx/_runtime/auth/strategies/ias-auth.js +76 -0
  101. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +8 -3
  102. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +15 -4
  103. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/expandToCQN.js +1 -1
  104. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/orderByToCQN.js +1 -1
  105. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/utils.js +1 -1
  106. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/ResourcePathParser.js +9 -0
  107. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/UriInfo.js +5 -1
  108. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/UriParser.js +12 -0
  109. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/utils/BufferedWriter.js +6 -2
  110. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/validator/RequestValidator.js +47 -7
  111. package/libx/_runtime/cds-services/adapter/odata-v4/to.js +1 -1
  112. package/libx/_runtime/cds-services/util/assert.js +4 -0
  113. package/libx/_runtime/common/aspects/relation.js +1 -1
  114. package/libx/_runtime/common/composition/data.js +61 -15
  115. package/libx/_runtime/common/composition/delete.js +0 -1
  116. package/libx/_runtime/common/composition/insert.js +0 -1
  117. package/libx/_runtime/common/composition/tree.js +4 -10
  118. package/libx/_runtime/common/composition/update.js +44 -21
  119. package/libx/_runtime/common/generic/auth/capabilities.js +8 -10
  120. package/libx/_runtime/common/generic/crud.js +1 -2
  121. package/libx/_runtime/common/generic/etag.js +4 -4
  122. package/libx/_runtime/common/generic/input.js +4 -4
  123. package/libx/_runtime/common/generic/paging.js +3 -3
  124. package/libx/_runtime/common/generic/put.js +3 -3
  125. package/libx/_runtime/common/generic/sorting.js +4 -4
  126. package/libx/_runtime/common/generic/temporal.js +3 -3
  127. package/libx/_runtime/common/i18n/messages.properties +0 -7
  128. package/libx/_runtime/common/utils/cqn2cqn4sql.js +11 -6
  129. package/libx/_runtime/common/utils/csn.js +0 -28
  130. package/libx/_runtime/common/utils/draft.js +8 -1
  131. package/libx/_runtime/common/utils/path.js +7 -1
  132. package/libx/_runtime/common/utils/resolveView.js +2 -3
  133. package/libx/_runtime/db/data-conversion/post-processing.js +3 -44
  134. package/libx/_runtime/db/generic/input.js +3 -3
  135. package/libx/_runtime/db/sql-builder/dataTypes.js +4 -0
  136. package/libx/_runtime/fiori/generic/activate.js +2 -2
  137. package/libx/_runtime/fiori/generic/before.js +40 -72
  138. package/libx/_runtime/fiori/generic/cancel.js +2 -2
  139. package/libx/_runtime/fiori/generic/delete.js +2 -2
  140. package/libx/_runtime/fiori/generic/edit.js +2 -2
  141. package/libx/_runtime/fiori/generic/new.js +2 -2
  142. package/libx/_runtime/fiori/generic/patch.js +49 -37
  143. package/libx/_runtime/fiori/generic/prepare.js +2 -2
  144. package/libx/_runtime/fiori/generic/read.js +27 -37
  145. package/libx/_runtime/fiori/utils/where.js +4 -2
  146. package/libx/_runtime/hana/Service.js +1 -3
  147. package/libx/_runtime/hana/conversion.js +3 -0
  148. package/libx/_runtime/hana/driver.js +33 -3
  149. package/libx/_runtime/hana/dynatrace.js +1 -0
  150. package/libx/_runtime/hana/search2Contains.js +12 -1
  151. package/libx/_runtime/hana/search2cqn4sql.js +10 -27
  152. package/libx/_runtime/hana/streaming.js +1 -0
  153. package/libx/_runtime/messaging/AMQPWebhookMessaging.js +4 -2
  154. package/libx/_runtime/messaging/common-utils/AMQPClient.js +1 -0
  155. package/libx/_runtime/messaging/enterprise-messaging-utils/getTenantInfo.js +5 -2
  156. package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +2 -0
  157. package/libx/_runtime/messaging/enterprise-messaging.js +62 -3
  158. package/libx/_runtime/messaging/outbox/utils.js +1 -1
  159. package/libx/_runtime/messaging/redis-messaging.js +1 -0
  160. package/libx/_runtime/remote/Service.js +2 -2
  161. package/libx/_runtime/remote/utils/client.js +8 -3
  162. package/libx/_runtime/remote/utils/data.js +7 -2
  163. package/libx/_runtime/sqlite/Service.js +18 -7
  164. package/libx/_runtime/sqlite/conversion.js +3 -0
  165. package/libx/_runtime/sqlite/convertAssocToOneManaged.js +3 -3
  166. package/libx/_runtime/sqlite/localized.js +8 -8
  167. package/libx/odata/afterburner.js +39 -7
  168. package/libx/odata/cqn2odata.js +6 -3
  169. package/libx/odata/grammar.pegjs +66 -18
  170. package/libx/odata/index.js +3 -2
  171. package/libx/odata/parser.js +1 -1
  172. package/libx/odata/utils.js +2 -0
  173. package/libx/rest/RestAdapter.js +62 -43
  174. package/libx/rest/middleware/parse.js +2 -1
  175. package/libx/rest/middleware/update.js +1 -1
  176. package/package.json +2 -2
  177. package/server.js +5 -4
  178. package/srv/mtx.cds +1 -1
  179. package/srv/mtx.js +4 -33
  180. package/lib/srv/adapters.js +0 -85
  181. package/lib/utils/resources/index.js +0 -48
  182. package/lib/utils/resources/tar.js +0 -49
  183. package/lib/utils/resources/utils.js +0 -11
  184. package/libx/_runtime/extensibility/activate.js +0 -69
  185. package/libx/_runtime/extensibility/add.js +0 -50
  186. package/libx/_runtime/extensibility/addExtension.js +0 -72
  187. package/libx/_runtime/extensibility/defaults.js +0 -34
  188. package/libx/_runtime/extensibility/handler/transformREAD.js +0 -121
  189. package/libx/_runtime/extensibility/handler/transformRESULT.js +0 -51
  190. package/libx/_runtime/extensibility/handler/transformWRITE.js +0 -64
  191. package/libx/_runtime/extensibility/linter/allowlist_checker.js +0 -373
  192. package/libx/_runtime/extensibility/linter/annotations_checker.js +0 -113
  193. package/libx/_runtime/extensibility/linter/checker_base.js +0 -20
  194. package/libx/_runtime/extensibility/linter/namespace_checker.js +0 -180
  195. package/libx/_runtime/extensibility/linter.js +0 -32
  196. package/libx/_runtime/extensibility/push.js +0 -118
  197. package/libx/_runtime/extensibility/service.js +0 -38
  198. package/libx/_runtime/extensibility/token.js +0 -57
  199. package/libx/_runtime/extensibility/utils.js +0 -131
  200. package/libx/_runtime/extensibility/validation.js +0 -50
  201. package/libx/_runtime/extensibility/views.js +0 -12
  202. package/srv/extensibility-service.cds +0 -60
  203. package/srv/extensibility-service.js +0 -1
  204. package/srv/extensions.cds +0 -8
  205. package/srv/model-provider.cds +0 -61
  206. package/srv/model-provider.js +0 -143
package/CHANGELOG.md CHANGED
@@ -4,6 +4,82 @@
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 6.2.2 - 2022-10-13
8
+
9
+ ### Fixed
10
+
11
+ - Fix environment variable `OLD_MTX`, allowing `cds build` to create artifacts for classic `@sap/cds-mtx` library
12
+
13
+ ## Version 6.2.1 - 2022-10-05
14
+
15
+ ### Fixed
16
+
17
+ - In the CDS configuration, custom profiles now have precedence over the (implicit) default `[development]` profile, irrespective of insertion order.
18
+ - `cds test` is now compatible with new `axios` 1.x
19
+
20
+ ## Version 6.2.0 - 2022-10-04
21
+
22
+ ### Added
23
+
24
+ - Types for using tagged template variants of several CQL constructs
25
+ - Types for calling shortcut versions of CQL constructs (`SELECT(...)` in addition to `SELECT.from(...)`, etc.)
26
+ - Types for `cds.test`
27
+ - Types for `cds.log().setFormat()`
28
+ - Support for `redis-messaging` (beta)
29
+ - Log the cds version when starting the server
30
+ - Support for non-root entities as the main draft entity
31
+ - Support for IAS authentication using kind `ias-auth`
32
+ - Warning if multiple installations of `@sap/cds` were found when serving requests
33
+ - Wildcard expansion `('*')` of properties in QL is now typed
34
+ - Support for extended models in custom transactions and background processes
35
+ - `cds build` logs detailed error messages if required service models cannot be resolved or aren't defined in custom build tasks.
36
+ - Support for additional data types `cds.UInt8`, `cds.Int16`, `cds.Int32`, `cds.Int64`
37
+ - Typings for `cds.utils`, `req.entity`
38
+ - Optimized server startup for projects with large models and high numbers of services.
39
+ Can be switched off by setting config `cds.features.precompile_edms = false` in case of problems.
40
+ - Set default header to `application/octet-stream` while sending binary to remote
41
+ - OData temporal query params `$at`, `$from`, `$to`, `$toInclusive` can be used in custom handlers
42
+ - Reserved keywords from compiler api available at `cds.compile.to.[cdl, sql.sqlite]`
43
+ - Improved `winston` integration in `cds.log`
44
+
45
+ ### Changed
46
+
47
+ - `cds.debug()` now returns undefined instead of falsy if debug is switched off. This allows usages like that:
48
+ ```js
49
+ const DEBUG = cds.debug('whatever')
50
+ DEBUG?.(...)
51
+ ```
52
+ - All MTX-related modules have been refactored and moved to `@sap/cds-mtxs`.
53
+ Ensure to also upgrade to latest version of `@sap/cds-mtxs` when upgrading `@sap/cds` to avoid any breaking change effects.
54
+ - SQLite database file endings have been changed to `.sqlite`, so third-party tools (e.g. VS Code extensions) can deduce the file type.
55
+ - Method `disconnect()` in db services empties db pool w/o removing db services. In special cases (like tests) cleaning-up db service should be done manually while deleting `cds.services.db` and `cds.db`.
56
+ - Prefer HANA driver that is required in package.json of project root
57
+
58
+ ### Fixed
59
+
60
+ - Queries like `SELECT.from(Foo).where({a:1}).or({b:2}).and({c:3})` erroneously resulted in `SELECT from Foo where (a=1 or b=2) and c=3`
61
+ - Signatures for QN `order_by` expressions are now in line with the capire doc
62
+ - Signatures for QL operations are now more specific
63
+ - `basic-auth` does not inherit users of `mocked-auth`
64
+ - `cds.localize` now ignores i18n files defined outside project scope.
65
+ - Allow `@Capabilities.NavigationRestrictions.RestrictedProperties` to be specified in the format `{ InsertRestrictions.Insertable: false }`
66
+ - Bound actions/functions while calling remote service
67
+ - `$search`: Search on localized projections/views does not always return the localized data
68
+ - `cds push` now shows better output for failed extension validations
69
+ - Aliased parameters in REST parser
70
+ - `cds.deploy` now logs the correct filename for multitenant SQLite
71
+ - HDI configuration data (e.g. `./cfg`, `.hdiignore`) and HANA native artifacts have not always been copied into the `sdc` folder of a MTX sidecar module
72
+ - OData URL to CQN parser (`cds.env.features.odata_new_parser`) now supports functions with no arguments
73
+ - Runtime exception for `PATCH` HTTP request with an empty payload body and read-only field
74
+ - Streams in draft caused SQL error
75
+ - Better response state handling during `cds deploy` to Cloud Foundry.
76
+ - Draft: patch on draft enabled entity with a composition of one
77
+ - Maximum stack trace exceeded in generic audit logging implementation
78
+ - The protocol adapter logs the decoded URI or the original one, if it is invalid
79
+ - REST: reject action calls with round brackets (parentheses). For example, the request `/Books(1)/bookShelf.CatalogService.rate()` is now rejected.
80
+ - `cds deploy` and `cds run/serve/watch` no longer print terminal escape sequences (`x1b...`) if they run non-interactively.
81
+ - Some fields in entities like `path` generated invalid sql
82
+
7
83
  ## Version 6.1.3 - 2022-09-13
8
84
 
9
85
  ### Added
@@ -38,13 +114,12 @@
38
114
  - `UPDATE` statement accepts empty objects: `UPDATE('Foo').with({ bar: {} })`
39
115
  - URI encoding of parameters in remote service calls
40
116
 
41
- ### Removed
42
-
43
117
  ## Version 6.1.1 - 2022-08-24
44
118
 
45
119
  ### Added
46
-
47
120
  - The configuration schema now includes `cds.extends` and `new-fields` (in `cds.xt.ExtensibilityService`)
121
+ - Ability to run extension validations as part of `cds lint`
122
+ - The `/-/cds/login` endpoint now also supports client credentials authentication
48
123
  - `srv.run(fn)` now accepts a function as first argument, which will be run in an active outer transaction, if any, or in a newly created one. This is in contrast to `srv.tx(fn)` which always creates a new tx.
49
124
  ```js
50
125
  cds.run (tx => { // nested operations are guaranteed to run in a tx
@@ -60,7 +135,7 @@
60
135
  - View resolving without model information doesn't crash
61
136
  - Unable to upload large attachments. Uploading a large attachment (base64 encoded) caused a runtime exception.
62
137
  - `cds.Query.then()` is using `AsyncResource.runInAsyncScope` from now on. → this avoids callstacks being cut off, e.g. in debuggers.
63
- - `cds.tx()` and `cds.context` have been fixed to avoid accidential fallbacks to auto-commit mode.
138
+ - `cds.tx()` and `cds.context` have been fixed to avoid accidental fallbacks to auto-commit mode.
64
139
  - HDI configuration data (e.g. `./cfg`, `.hdiignore`) is now included in the `resources.tgz` file which is required for Streamlined MTX.
65
140
  - `cds deploy` accepts in addition to `VCAP_SERVICES` also `TARGET_CONTAINER` and `SERVICE_REPLACEMENTS` from vcap file when using `--vcap-file` parameter.
66
141
  - `cds build` doesn't duplicate CSV files that are contained in `db/src/**`.
@@ -69,12 +144,12 @@
69
144
  - Unhandled promise rejection in `expand` handling
70
145
  - `cds.context.model` middleware is not mounted for not extensible services
71
146
  - `cds.context` continuation was sometimes not reset in REST adapter
72
- - Requests don't fail with `RangeError: Unable to get service from service map due to error: Invalid time value` anymore
73
147
 
74
148
  ## Version 6.1.0 - 2022-08-10
75
149
 
76
150
  ### Added
77
151
 
152
+ - Support for `@sap/cds-mtxs` in `enterprise-messaging`
78
153
  - Detailed information about pool state: `borrowed`, `pending`, `size`, `available`, `max` to the timeout error
79
154
  - Odata v2 payloads for `cds.Time` are converted from hh:mm:ss to PThhHmmMssS e.g. 12:34:56 to PT12H34M56S if provided in hh:mm:ss format
80
155
  - Odata v2 payloads for `cds.Integer` are converted to String if not provided as String
@@ -84,7 +159,7 @@
84
159
  - New OData parser supports $filter with "in" operator, e.g. `$filter=ID in (1,2,3)`
85
160
  - `cds build` copies `package.json` and `.cdsrc.json` into _main folder of MTX sidecar app.
86
161
  - New OData parser supports null parameter in function/action, e.g `/findBooks(author=1,title=null)`
87
- - New enviroment variable `schemas` contains locations for json schemas validating `package.json`, `.cdsrc.json` and `.cdsrc-private.json` in VS Code
162
+ - New environment variable `schemas` contains locations for json schemas validating `package.json`, `.cdsrc.json` and `.cdsrc-private.json` in VS Code
88
163
  - `cds.test` can now listen on a fixed port by way of additional arguments '--port', '<PORT_NUMBER>
89
164
  - `cds.requires.db.kind = 'sql-mt'` is introduced as a shorthand for
90
165
  ```js
@@ -372,7 +447,7 @@ Note that this is a breaking change for appliations that rely on error sanitizat
372
447
 
373
448
  - We don't rely on `global.cds` anymore -> allows to load and correctly work with multiple versions of `cds`
374
449
  - Improved shutdown for AMQP connections and file listeners
375
- - Using `CQL` with a tagged template string `SELECT from Foo { null as boo }` throwed an exception.
450
+ - Using `CQL` with a tagged template string `SELECT from Foo { null as boo }` threw an exception.
376
451
  - In case of `MULTIPLE_ERRORS` throw an `Error` instead of an object
377
452
  - `cds build` ensures correct precedence of feature annotations. Fixes `Duplicate assignment` compilation errors.
378
453
  - Compatibility with former support to find service `@impl: 'relative/to/cdw'`.
@@ -754,7 +829,7 @@ In such scenarios, now the HTTP `404 Not Found` status code is returned rather t
754
829
  - `cds version` now always prints the version of `@sap/cds-dk`, especially if `cds version` was called from within an npm script, i.e. not from `cds-dk`'s CLI.
755
830
  - Better error message in case destination of Remote Service isn’t found
756
831
  - Differentiate between draft already exists and entity locked
757
- - OData adapter: roll back transaction before rethrowing standard error in case of atomicity group
832
+ - OData adapter: roll back transaction before re-throwing standard error in case of atomicity group
758
833
  - Results of actions/functions do not ignore custom data when using `$expand` query option
759
834
  - `req.data` is available in custom error handler in case of deserialization error thrown by legacy OData server
760
835
  - Joining entities with renamed foreign keys (limited to single-level projections)
package/apis/cds.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import * as ql from './ql'
1
2
 
2
3
  type cds_facade = import('./core')
3
4
  & import('./models')
@@ -7,15 +8,26 @@ type cds_facade = import('./core')
7
8
  & import('./services').cds
8
9
  & import('./services').QueryAPI
9
10
  & import('./log')
11
+ & import('./utils')
12
+ & import('./test')
10
13
 
11
14
  declare global {
12
15
  const cds : cds_facade
13
- class SELECT<T> extends cds.ql.SELECT<T>{}
14
- class INSERT<T> extends cds.ql.INSERT<T>{}
15
- class UPDATE<T> extends cds.ql.UPDATE<T>{}
16
- class DELETE<T> extends cds.ql.DELETE<T>{}
17
- class CREATE<T> extends cds.ql.CREATE<T>{}
18
- class DROP<T> extends cds.ql.DROP<T>{}
16
+ // these provide the functionality from SELECT, INSERT, etc in the global facade
17
+ const SELECT: typeof cds.ql.SELECT
18
+ const INSERT: typeof cds.ql.INSERT
19
+ const UPDATE: typeof cds.ql.UPDATE
20
+ const DELETE: typeof cds.ql.DELETE
21
+ const CREATE: typeof cds.ql.CREATE
22
+ const DROP: typeof cds.ql.DROP
23
+
24
+ // and these allow us to use them as type too, i.e. `const q: SELECT<Book> = ...`
25
+ type SELECT<T> = ql.SELECT<T>
26
+ type INSERT<T> = ql.INSERT<T>
27
+ type UPDATE<T> = ql.UPDATE<T>
28
+ type DELETE<T> = ql.DELETE<T>
29
+ type CREATE<T> = ql.CREATE<T>
30
+ type DROP<T> = ql.DROP<T>
19
31
  }
20
32
 
21
33
  export = cds
package/apis/connect.d.ts CHANGED
@@ -9,7 +9,7 @@ declare class cds {
9
9
  * Connects to a specific datasource.
10
10
  * @see [capire](https://cap.cloud.sap/docs/node.js/api#cds-connect)
11
11
  */
12
- to (datasource?: string, options?: ConnectOptions) : Service & Promise<Service>
12
+ to (datasource?: string, options?: ConnectOptions) : Promise<Service>
13
13
 
14
14
  /**
15
15
  * Connects the primary datasource.
package/apis/cqn.d.ts CHANGED
@@ -45,7 +45,7 @@ type name = string
45
45
  type source = ( ref | SELECT ) & { as?: name, join?:name, on?:xpr }
46
46
  export type column_expr = expr & { as?: name, cast?:any, expand?: column_expr[], inline?: column_expr[] }
47
47
  export type predicate = _xpr
48
- type ordering_term = expr & { asc?:true, desc?:true }
48
+ type ordering_term = expr & { sort?: "asc"|"desc", nulls?: "first"|"last" }
49
49
 
50
50
  export type expr = ref | val | xpr | SELECT
51
51
  type ref = {ref:( name & { id?:string, where?:expr, args?:expr[] } )[]}
package/apis/log.d.ts CHANGED
@@ -53,12 +53,8 @@ declare type LogFactory = {
53
53
  * ```
54
54
  *
55
55
  * The formatter shall return an array of arguments, which are passed to the logger (for example, `console.log()`)
56
- *
57
- * @param module logger name
58
- * @param level log level
59
- * @param args additional arguments
60
56
  */
61
- format(module: string, level: number, args: any[]): any[]
57
+ format: Formatter
62
58
  }
63
59
 
64
60
  declare class Logger {
@@ -107,6 +103,28 @@ declare class Logger {
107
103
  * @returns whether 'error' level is active
108
104
  */
109
105
  _error: boolean
106
+
107
+ /**
108
+ * Change the format for this logger instance:
109
+ * ```
110
+ * cds.log('foo').setFormat((module, level, ...args) => [ '[', module, ']', ...args ])
111
+ * ```
112
+ *
113
+ * The formatter shall return an array of arguments, which are passed to the logger (for example, `console.log()`)
114
+ */
115
+ setFormat(formatter: Formatter)
116
+ }
117
+
118
+ declare type Formatter = {
119
+ /**
120
+ * Custom format function
121
+ *
122
+ * @param module logger name
123
+ * @param level log level
124
+ * @param args additional arguments
125
+ * @returns an array of arguments, which are passed to the logger (for example, `console.log()`)
126
+ */
127
+ (module: string, level: number, args: any[]): any[]
110
128
  }
111
129
 
112
130
  declare type Log = {
package/apis/ql.d.ts CHANGED
@@ -17,10 +17,26 @@ export class cds_ql {
17
17
 
18
18
  export type PK = number | string | object
19
19
 
20
+ interface QLExtensions {
21
+ as: (alias: string) => void
22
+ }
23
+
20
24
  // to support path expressions: https://pages.github.tools.sap/cap/docs/java/query-api#path-expressions
21
25
  // `Book.title` == `Proxy<Book>.title()`
22
- type Proxy<T> = {
23
- [Key in keyof T]: () => Proxy<T[Key]>
26
+
27
+ /**
28
+ * This is a marker interface to determine if a property supports subselecting. That is:
29
+ *
30
+ * [1] SELECT.from(Books, b => b.author)
31
+ * means: "select all books and project each book's author"
32
+ * [2] SELECT.from(Books, b => b.author(a => a.ID))
33
+ * means: "select all books, subselect each book's author's ID
34
+ *
35
+ */
36
+ type Subqueryable <T> = ((fn:((a:T)=>any)|"*") => T)
37
+
38
+ type Proxy_<T> = {
39
+ [Key in keyof T]: Proxy<T[Key]> //& QLExtensions
24
40
  } & {
25
41
  /**
26
42
  * Accesses any nested attribute based on a path:
@@ -29,100 +45,146 @@ type Proxy<T> = {
29
45
  * To still have access to typed results, use
30
46
  * `X.a().b().c().d()` instead.
31
47
  */
32
- get: (path: string) => Proxy<unknown>
33
- }
48
+ get: (path: string) => any // Proxy<unknown>
49
+ } & QLExtensions
50
+
51
+ type Proxy<T> = (T extends Subqueryable<infer U>
52
+ ? (Omit<T, ""> & Subqueryable<Proxy<U>>) // drop ((x: T) => T) in favour of (x: Proxy<T>) => Proxy<T>)
53
+ : (Proxy_<T>))
54
+ & QLExtensions
34
55
 
35
56
  // any class (not value) of array to represent plural types used in cds-typer.
36
57
  // Mainly used as pattern match for SingularType
37
- type ArrayClass = {new():Array<unknown>}
58
+ //type ArrayConstructable = Constructable<Array<unknown>>
59
+ interface ArrayConstructable<T> {
60
+ new(...args: any[]): T
61
+ }
38
62
 
39
63
  // concrete singular type.
40
- // `SingularType<typeof Books>` == `Book`.
41
- type SingularType<T extends ArrayClass> = InstanceType<T>[number]
64
+ // `SingularType<Books>` == `Book`.
65
+ type SingularType<T extends ArrayConstructable<T>> = InstanceType<T>[number]
66
+
67
+ // Alias for projections
68
+ // https://cap.cloud.sap/docs/node.js/cds-ql?q=projection#projection-functions
69
+ type Projection<T> = (e:T)=>void
70
+
71
+ // Type for query pieces that can either be chained to build more complex queries or
72
+ // awaited to materialise the result:
73
+ // `Awaitable<SELECT<Book>, Book> = SELECT<Book> & Promise<Book>`
74
+ //
75
+ // While the benefit is probably not immediately obvious as we don't exactly
76
+ // save a lot of typing over explicitly writing `SELECT<Book> & Promise<Book>`,
77
+ // it makes the semantics more explicit. Also sets us up for when TypeScript ever
78
+ // improves their generics to support:
79
+ //
80
+ // `Awaitable<T> = T extends unknown<infer I> ? (T & Promise<I>) : never`
81
+ // (at the time of writing, infering the first generic parameter of ANY type
82
+ // does not seem to be possible.)
83
+ type Awaitable<T, I> = T & Promise<I>
84
+
85
+ // all the functionality of an instance of SELECT, but directly callable:
86
+ // new SELECT(...).(...) == SELECT(...)
87
+ export type StaticSELECT<T> = typeof SELECT
88
+ & ((...columns:string[]) => SELECT<T>)
89
+ & ((columns:string[]) => SELECT<T>)
90
+ & (TaggedTemplateQueryPart<SELECT<T>>)
91
+ & SELECT_one // as it is not directly quantified, ...
92
+ & SELECT_from // ...we should expect both a scalar and a list
42
93
 
43
94
  declare class QL {
44
- SELECT : typeof SELECT & ((...columns:string[]) => SELECT<any>) & ((columns:string[]) => SELECT<any>)
45
- INSERT : typeof INSERT & ((...entries:object[]) => INSERT<any>) & ((entries:object[]) => INSERT<any>)
46
- UPDATE : typeof UPDATE & typeof UPDATE.entity
95
+ SELECT : StaticSELECT<T>
96
+ INSERT : typeof INSERT
97
+ & ((...entries:object[]) => INSERT<any>) & ((entries:object[]) => INSERT<any>)
98
+ UPDATE : typeof UPDATE
99
+ & typeof UPDATE.entity
47
100
  DELETE : typeof DELETE
48
101
  CREATE : typeof CREATE
49
102
  DROP : typeof DROP
50
103
  }
51
104
 
52
- // (new QL).SELECT.from('Foo').byKey(11).a
53
-
54
-
105
+ // used as a catch-all type for using tagged template strings: SELECT `foo`. from `bar` etc.
106
+ // the resulting signatures are actually not very strongly typed, but they at least accept template strings
107
+ // when run in strict mode.
108
+ // This signature has to be added to a method as intersection type.
109
+ // Defining overloads with it will override preceding signatures and the other way around.
110
+ type TaggedTemplateQueryPart<T> = (strings: TemplateStringsArray, ...params?: unknown[]) => T
55
111
 
56
112
  export class SELECT<T> extends ConstructedQuery {
57
113
  static one : SELECT_one & { from: SELECT_one }
58
114
  static distinct : typeof SELECT
59
- static from : SELECT_from
60
- from (entity: Definition | string, primaryKey? : PK, projection? : (e:any)=>void) : this
115
+ static from : SELECT_from
116
+ from: TaggedTemplateQueryPart<this>
117
+ & ((entity: Definition | string, primaryKey? : PK, projection? : Projection<unknown>) => this)
61
118
  byKey (primaryKey? : PK) : this
62
- columns (projection:(e:T)=>void) : this
63
- columns (...col:string[]) : this
64
- where (predicate:object) : this
65
- where (...expr : any[]) : this
66
- and (predicate:object) : this
67
- and (...expr : any[]) : this
68
- having (...expr : string[]) : this
69
- having (predicate:object) : this
70
- groupBy (...expr : string[]) : this
71
- orderBy (...expr : string[]) : this
72
- limit (rows : number, offset? : number) : this
119
+ columns: TaggedTemplateQueryPart<this>
120
+ & ((projection: Projection<T>) => this)
121
+ & ((...col:string[]) => this)
122
+ where: TaggedTemplateQueryPart<this>
123
+ & ((predicate:object) => this)
124
+ & ((...expr : any[]) => this)
125
+ and: TaggedTemplateQueryPart<this>
126
+ & ((predicate:object) => this)
127
+ & ((...expr : any[]) => this)
128
+ having: TaggedTemplateQueryPart<this>
129
+ & ((...expr : string[]) => this)
130
+ & ((predicate:object) => this)
131
+ groupBy: TaggedTemplateQueryPart<this>
132
+ & ((...expr : string[]) => this)
133
+ orderBy: TaggedTemplateQueryPart<this>
134
+ & ((...expr : string[]) => this)
135
+ limit: TaggedTemplateQueryPart<this>
136
+ & ((rows : number, offset? : number) => this)
73
137
  forSharedLock () : this
74
138
  forUpdate () : this
75
139
  SELECT : CQN.SELECT
76
140
  }
77
141
 
78
- type SELECT_one =
79
- ((entity: Definition | string, primaryKey? : PK, projection? : (e:any)=>void) => SELECT<any>)
80
142
 
143
+ type SELECT_one =
81
144
  // calling with class
82
- & (<T extends ArrayClass>
83
- (entityType: T)
84
- => SELECT<SingularType<T>> & Promise<SingularType<T>>)
145
+ (<T extends ArrayConstructable>
146
+ (entityType: T, projection?: Projection<Proxy<SingularType<T>>>)
147
+ => Awaitable<SELECT<SingularType<T>>, SingularType<T>>)
85
148
  &
86
- (<T extends ArrayClass>
87
- (entityType: T, projection: (e: Proxy<SingularType<T>>) => void)
88
- => SELECT<SingularType<T>> & Promise<SingularType<T>>)
89
- &
90
- (<T extends ArrayClass>
91
- (entityType: T, primaryKey : PK, projection: (e: Proxy<SingularType<T>>) => void)
92
- => SELECT<SingularType<T>> & Promise<SingularType<T>>)
93
-
94
-
95
- & (<T> (entity: T[], projection? : (e:T)=>void) => SELECT<T> & Promise<T>)
96
- & (<T> (entity: T[], primaryKey : PK, projection? : (e:T)=>void) => SELECT<T> & Promise<T>)
97
- & (<T> (entity: {new():T}, projection? : (e:T)=>void) => SELECT<T> & Promise<T>)
98
- & (<T> (entity: {new():T}, primaryKey : PK, projection? : (e:T)=>void) => SELECT<T> & Promise<T>)
99
-
149
+ (<T extends ArrayConstructable>
150
+ (entityType: T, primaryKey : PK, projection?: Projection<Proxy<SingularType<T>>>)
151
+ => Awaitable<SELECT<SingularType<T>>, SingularType<T>>)
100
152
 
153
+ & ((entity: Definition | string, primaryKey? : PK, projection? : Projection<unknown>) => SELECT<any>)
154
+ & (<T> (entity: T[], projection? : Projection<T>) => Awaitable<SELECT<T>, T>)
155
+ & (<T> (entity: T[], primaryKey : PK, projection? : Projection<T>) => Awaitable<SELECT<T>, T>)
156
+ & (<T> (entity: {new():T}, projection? : Projection<T>) => Awaitable<SELECT<T>, T>)
157
+ & (<T> (entity: {new():T}, primaryKey : PK, projection? : Projection<T>) => Awaitable<SELECT<T>, T>)
101
158
 
102
159
  type SELECT_from =
103
- // calling with class
104
- (<T extends ArrayClass>
105
- (entityType: T)
106
- => SELECT<SingularType<T>> & Promise<SingularType<T>>)
160
+ // tagged template
161
+ TaggedTemplateQueryPart<Awaitable<SELECT<unknown>, InstanceType<unknown>>>
107
162
  &
108
- (<T extends ArrayClass>
109
- (entityType: T, projection: (e: Proxy<SingularType<T>>) => void)
110
- => SELECT<SingularType<T>> & Promise<SingularType<T>>)
163
+ // calling with class
164
+ (<T extends ArrayConstructable>
165
+ (entityType: T, projection?: Projection<Proxy<SingularType<T>>>)
166
+ => Awaitable<SELECT<T>, InstanceType<T>>)
111
167
  &
112
- (<T extends ArrayClass>
113
- (entityType: T, primaryKey : PK, projection: (e: Proxy<SingularType<T>>) => void)
114
- => SELECT<SingularType<T>> & Promise<SingularType<T>>)
168
+ (<T extends ArrayConstructable>
169
+ (entityType: T, primaryKey : PK, projection?: Projection<SingularType<T>>)
170
+ => Awaitable<SELECT<T>, InstanceType<T>>)
115
171
  // calling with definition
116
- & ((entity: Definition | string, primaryKey? : PK, projection? : (e:any)=>void) => SELECT<any>)
172
+ & ((entity: Definition | string, primaryKey? : PK, projection? : Projection<unknown>) => SELECT<any>)
117
173
  // calling with concrete list
118
- & (<T> (entity: T[], projection? : (e:T)=>void) => SELECT<T> & Promise<T[]>)
119
- & (<T> (entity: T[], primaryKey : PK, projection? : (e:T)=>void) => SELECT<T> & Promise<T>)
174
+ & (<T> (entity: T[], projection? : Projection<T>) => SELECT<T> & Promise<T[]>)
175
+ & (<T> (entity: T[], primaryKey : PK, projection? : Projection<T>) => Awaitable<SELECT<T>, T>)
120
176
 
121
177
 
122
178
  export class INSERT<T> extends ConstructedQuery {
179
+ // cds-typer plural
180
+ static into <T extends ArrayConstructable> (entity:T, entries? : object | object[]) : INSERT<SingularType<T>>
181
+ into <T extends ArrayConstructable> (entity:T) : this
182
+
183
+ static into: TaggedTemplateQueryPart<INSERT<T>>
123
184
  static into (entity : Definition | string, entries? : object | object[]) : INSERT<any>
124
185
  static into <T> (entity:Constructable<T>, entries? : object | object[]) : INSERT<T>
125
186
  static into <T> (entity:T, entries? : T | object | object[]) : INSERT<T>
187
+ into: TaggedTemplateQueryPart<this>
126
188
  into (entity : Definition | string) : this
127
189
  data (block : (e:T)=>void) : this
128
190
  entries (...entries : object[]) : this
@@ -133,7 +195,7 @@ export class INSERT<T> extends ConstructedQuery {
133
195
  }
134
196
 
135
197
  export class DELETE<T> extends ConstructedQuery {
136
- static from (entity : Definition | string, primaryKey? : PK) : DELETE<any>
198
+ static from (entity : Definition | string | ArrayConstructable, primaryKey? : PK) : DELETE<any>
137
199
  byKey (primaryKey? : PK) : this
138
200
  where (predicate:object) : this
139
201
  where (...expr : any[]) : this
@@ -143,14 +205,19 @@ export class DELETE<T> extends ConstructedQuery {
143
205
  }
144
206
 
145
207
  export class UPDATE<T> extends ConstructedQuery {
208
+ // cds-typer plural
209
+ static entity <T extends ArrayConstructable> (entity:T, primaryKey? : PK) : UPDATE<SingularType<T>>
210
+
146
211
  static entity (entity : Definition | string, primaryKey? : PK) : UPDATE<any>
147
212
  static entity <T> (entity:Constructable<T>, primaryKey? : PK) : UPDATE<T>
148
213
  static entity <T> (entity:T, primaryKey? : PK) : UPDATE<T>
149
214
  byKey (primaryKey? : PK) : this
150
215
  // with (block: (e:T)=>void) : this
151
216
  // set (block: (e:T)=>void) : this
152
- set (data:object) : this
153
- with (data:object) : this
217
+ set: TaggedTemplateQueryPart<this>
218
+ & ((data:object) => this)
219
+ with: TaggedTemplateQueryPart<this>
220
+ & ((data:object) => this)
154
221
  where (predicate:object) : this
155
222
  where (...expr : any[]) : this
156
223
  and (predicate:object) : this
@@ -84,6 +84,11 @@ export class Service extends QueryAPI {
84
84
  impl: String | ServiceImpl
85
85
  })
86
86
 
87
+ /**
88
+ * The name of the service
89
+ */
90
+ name: string
91
+
87
92
  /**
88
93
  * The model from which the service's definition was loaded
89
94
  * @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-reflect)
@@ -304,6 +309,12 @@ interface EventContext {
304
309
  method : string
305
310
  path : string
306
311
  target : Definition
312
+ /**
313
+ * Shortcut to {@link target.name}
314
+ *
315
+ * @see https://cap.cloud.sap/docs/node.js/events#req-entity
316
+ */
317
+ entity: string
307
318
  query : Query
308
319
 
309
320
  reply (results) : void
package/apis/test.d.ts ADDED
@@ -0,0 +1,61 @@
1
+ import { AxiosInstance } from 'axios';
2
+ import chai from 'chai';
3
+ import * as main_cds from './cds';
4
+ import * as http from 'http';
5
+ import { Service } from './services';
6
+
7
+ declare class Axios {
8
+ get axios(): AxiosInstance;
9
+
10
+ get : AxiosInstance['get'];
11
+ put : AxiosInstance['put'];
12
+ post : AxiosInstance['post'];
13
+ patch : AxiosInstance['patch'];
14
+ delete : AxiosInstance['delete'];
15
+ options : AxiosInstance['options'];
16
+
17
+ get GET() : Axios['get'];
18
+ get PUT() : Axios['put'];
19
+ get POST() : Axios['post'];
20
+ get PATCH() : Axios['patch'];
21
+ get DELETE() : Axios['delete'];
22
+ get OPTIONS() : Axios['options'];
23
+ }
24
+
25
+ declare class DataUtil {
26
+ delete(db?: Service): Promise<void>;
27
+ reset(db?: Service): Promise<void>;
28
+ autoReset(enabled: boolean): this;
29
+ }
30
+
31
+ declare class Test extends Axios {
32
+ run(cmd: string, ...args: string[]): this;
33
+ in(...paths: string[]): this;
34
+ verbose(v: boolean): this;
35
+
36
+ get chai(): typeof chai;
37
+ get expect(): typeof chai.expect;
38
+ get assert(): typeof chai.assert;
39
+ get data(): DataUtil;
40
+ get cds(): typeof main_cds;
41
+
42
+ then(r: (args: { server: http.Server, url: string }) => void): void;
43
+
44
+ // get sleep(): (ms: number) => Promise<void>;
45
+ // get spy(): <T, K extends keyof T>(o: T, f: K) => T[K] extends (...args: infer TArgs) => infer TReturnValue
46
+ // ? Spy<TArgs, TReturnValue>
47
+ // : Spy;
48
+ }
49
+
50
+ // typings for spy inspired by @types/sinon
51
+ // interface Spy<TArgs extends any[] = any[], TReturnValue = any> {
52
+ // (...args: TArgs): TReturnValue;
53
+ // called: number;
54
+ // restore(): (...args: TArgs) => TReturnValue;
55
+ // }
56
+
57
+ export = cds
58
+
59
+ declare class cds {
60
+ test(projectDir: string): Test;
61
+ }
@@ -0,0 +1,15 @@
1
+ export = cds
2
+
3
+ declare class cds {
4
+
5
+ /**
6
+ * Provides a set of utility functionss
7
+ */
8
+ utils : {
9
+ /**
10
+ * Generates a new v4 UUID
11
+ * @see https://cap.cloud.sap/docs/node.js/cds-facade#cds-utils
12
+ */
13
+ uuid () : string
14
+ }
15
+ }
@@ -246,6 +246,7 @@ cds.on('served', ()=>{
246
246
 
247
247
  // install middlewares once
248
248
  if (any) {
249
+ // eslint-disable-next-line cds/no-missing-dependencies
249
250
  const router = require('express').Router()
250
251
  // UI5 component
251
252
  router.get ('/:service/:entity/app/Component.js', ({ params }, resp) => resp.send(_componentJs(params.service, params.entity)))