@sap/cds 6.0.2 → 6.1.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.
- package/CHANGELOG.md +153 -19
- package/apis/cds.d.ts +11 -7
- package/apis/log.d.ts +48 -0
- package/apis/ql.d.ts +72 -15
- package/bin/build/buildTaskHandler.js +5 -2
- package/bin/build/constants.js +4 -1
- package/bin/build/provider/buildTaskHandlerEdmx.js +11 -39
- package/bin/build/provider/buildTaskHandlerFeatureToggles.js +13 -32
- package/bin/build/provider/buildTaskHandlerInternal.js +56 -4
- package/bin/build/provider/buildTaskProviderInternal.js +22 -14
- package/bin/build/provider/hana/index.js +8 -7
- package/bin/build/provider/java/index.js +18 -8
- package/bin/build/provider/mtx/index.js +7 -4
- package/bin/build/provider/mtx/resourcesTarBuilder.js +64 -35
- package/bin/build/provider/mtx-extension/index.js +57 -0
- package/bin/build/provider/mtx-sidecar/index.js +46 -18
- package/bin/build/provider/nodejs/index.js +34 -13
- package/bin/build/util.js +6 -4
- package/bin/deploy/to-hana/cfUtil.js +7 -2
- package/bin/deploy/to-hana/hana.js +6 -3
- package/bin/serve.js +8 -13
- package/lib/compile/{index.js → cds-compile.js} +0 -0
- package/lib/compile/extend.js +15 -5
- package/lib/compile/minify.js +1 -15
- package/lib/compile/parse.js +1 -1
- package/lib/compile/resolve.js +2 -2
- package/lib/compile/to/srvinfo.js +6 -4
- package/lib/{deploy.js → dbs/cds-deploy.js} +8 -8
- package/lib/env/{index.js → cds-env.js} +1 -17
- package/lib/env/{requires.js → cds-requires.js} +24 -3
- package/lib/env/defaults.js +7 -1
- package/lib/env/schemas/cds-package.json +11 -0
- package/lib/env/schemas/cds-rc.json +605 -0
- package/lib/index.js +20 -17
- package/lib/log/{errors.js → cds-error.js} +1 -1
- package/lib/log/{index.js → cds-log.js} +0 -0
- package/lib/ql/SELECT.js +1 -1
- package/lib/ql/{index.js → cds-ql.js} +0 -0
- package/lib/req/cds-context.js +1 -1
- package/lib/req/context.js +35 -7
- package/lib/req/locale.js +5 -1
- package/lib/{serve → srv}/adapters.js +23 -19
- package/lib/{connect → srv}/bindings.js +0 -0
- package/lib/{connect/index.js → srv/cds-connect.js} +1 -1
- package/lib/{serve/index.js → srv/cds-serve.js} +1 -1
- package/lib/{serve → srv}/factory.js +2 -3
- package/lib/{serve/Service-api.js → srv/srv-api.js} +14 -6
- package/lib/{serve/Service-dispatch.js → srv/srv-dispatch.js} +3 -2
- package/lib/{serve/Service-handlers.js → srv/srv-handlers.js} +10 -0
- package/lib/{serve/Service-methods.js → srv/srv-methods.js} +10 -8
- package/lib/srv/srv-models.js +206 -0
- package/lib/{serve/Transaction.js → srv/srv-tx.js} +6 -1
- package/lib/utils/{tests.js → cds-test.js} +2 -2
- package/lib/utils/cds-utils.js +146 -0
- package/lib/utils/index.js +2 -136
- package/lib/utils/jest.js +43 -0
- package/lib/utils/resources/index.js +14 -24
- package/lib/utils/resources/tar.js +18 -41
- package/libx/_runtime/auth/index.js +13 -10
- package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +9 -20
- package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +1 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +19 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +8 -11
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/delete.js +1 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +6 -19
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +1 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +8 -10
- package/libx/_runtime/cds-services/adapter/odata-v4/to.js +38 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/handlerUtils.js +2 -6
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/readAfterWrite.js +8 -5
- package/libx/_runtime/cds-services/services/utils/differ.js +4 -0
- package/libx/_runtime/cds-services/util/errors.js +1 -29
- package/libx/_runtime/common/constants/events.js +1 -3
- package/libx/_runtime/common/i18n/messages.properties +2 -1
- package/libx/_runtime/common/perf/index.js +10 -15
- package/libx/_runtime/common/utils/cqn2cqn4sql.js +0 -1
- package/libx/_runtime/common/utils/entityFromCqn.js +8 -5
- package/libx/_runtime/common/utils/template.js +1 -1
- package/libx/_runtime/db/Service.js +2 -14
- package/libx/_runtime/db/expand/expandCQNToJoin.js +28 -25
- package/libx/_runtime/db/generic/input.js +4 -0
- package/libx/_runtime/db/sql-builder/SelectBuilder.js +37 -18
- package/libx/_runtime/extensibility/activate.js +47 -47
- package/libx/_runtime/extensibility/add.js +19 -13
- package/libx/_runtime/extensibility/addExtension.js +17 -13
- package/libx/_runtime/extensibility/defaults.js +25 -30
- package/libx/_runtime/extensibility/linter/allowlist_checker.js +373 -0
- package/libx/_runtime/extensibility/linter/annotations_checker.js +113 -0
- package/libx/_runtime/extensibility/linter/checker_base.js +20 -0
- package/libx/_runtime/extensibility/linter/namespace_checker.js +180 -0
- package/libx/_runtime/extensibility/linter.js +32 -0
- package/libx/_runtime/extensibility/push.js +78 -21
- package/libx/_runtime/extensibility/service.js +29 -12
- package/libx/_runtime/extensibility/token.js +56 -0
- package/libx/_runtime/extensibility/validation.js +6 -9
- package/libx/_runtime/fiori/generic/activate.js +0 -4
- package/libx/_runtime/fiori/generic/edit.js +1 -9
- package/libx/_runtime/fiori/generic/new.js +3 -28
- package/libx/_runtime/fiori/generic/patch.js +6 -7
- package/libx/_runtime/fiori/generic/prepare.js +11 -18
- package/libx/_runtime/fiori/generic/read.js +11 -1
- package/libx/_runtime/fiori/utils/handler.js +0 -17
- package/libx/_runtime/hana/Service.js +0 -1
- package/libx/_runtime/hana/conversion.js +12 -1
- package/libx/_runtime/hana/customBuilder/CustomFunctionBuilder.js +4 -3
- package/libx/_runtime/hana/customBuilder/CustomSelectBuilder.js +5 -0
- package/libx/_runtime/hana/pool.js +6 -10
- package/libx/_runtime/hana/search2Contains.js +0 -5
- package/libx/_runtime/hana/search2cqn4sql.js +1 -0
- package/libx/_runtime/messaging/AMQPWebhookMessaging.js +18 -19
- package/libx/_runtime/messaging/file-based.js +1 -0
- package/libx/_runtime/messaging/outbox/utils.js +1 -1
- package/libx/_runtime/messaging/service.js +11 -6
- package/libx/_runtime/remote/utils/client.js +6 -2
- package/libx/_runtime/remote/utils/data.js +5 -0
- package/libx/_runtime/sqlite/Service.js +0 -1
- package/libx/odata/afterburner.js +79 -2
- package/libx/odata/cqn2odata.js +9 -7
- package/libx/odata/grammar.pegjs +161 -77
- package/libx/odata/index.js +9 -3
- package/libx/odata/parser.js +1 -1
- package/libx/odata/utils.js +39 -5
- package/libx/rest/RestAdapter.js +1 -2
- package/libx/rest/middleware/delete.js +4 -5
- package/libx/rest/middleware/parse.js +3 -2
- package/package.json +3 -3
- package/server.js +1 -1
- package/srv/extensibility-service.cds +6 -3
- package/srv/model-provider.cds +3 -1
- package/srv/model-provider.js +84 -104
- package/srv/mtx.js +7 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +0 -240
package/CHANGELOG.md
CHANGED
|
@@ -4,27 +4,161 @@
|
|
|
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.1.0 - 2022-08-10
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Detailed information about pool state: `borrowed`, `pending`, `size`, `available`, `max` to the timeout error
|
|
12
|
+
- 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
|
|
13
|
+
- Odata v2 payloads for `cds.Integer` are converted to String if not provided as String
|
|
14
|
+
- New OData parser supports aliased parameters e.g. `...function(ID=@p)?@p=5`
|
|
15
|
+
- Support for locale "en_US_x_saprigi"
|
|
16
|
+
- Parameter `rows` in ql API function `limit` can be omitted for remote services, e.g. `SELECT.limit(undefined, 5)`
|
|
17
|
+
- New OData parser supports $filter with "in" operator, e.g. `$filter=ID in (1,2,3)`
|
|
18
|
+
- `cds build` copies `package.json` and `.cdsrc.json` into _main folder of MTX sidecar app.
|
|
19
|
+
- New OData parser supports null parameter in function/action, e.g `/findBooks(author=1,title=null)`
|
|
20
|
+
- New enviroment variable `schemas` contains locations for json schemas validating `package.json`, `.cdsrc.json` and `.cdsrc-private.json` in VS Code
|
|
21
|
+
- `cds.test` can now listen on a fixed port by way of additional arguments '--port', '<PORT_NUMBER>
|
|
22
|
+
- `cds.requires.db.kind = 'sql-mt'` is introduced as a shorthand for
|
|
23
|
+
```js
|
|
24
|
+
"db": {
|
|
25
|
+
"kind": "sqlite",
|
|
26
|
+
"[production]": {
|
|
27
|
+
"kind": "hana-mt"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
- `cds build` support for Streamlined MTX extension projects based on build task `mtx-extension`
|
|
32
|
+
- TS definitions for `SELECT.forSharedLock` and `SELECT.forUpdate`
|
|
33
|
+
- TS definitions for `log`
|
|
34
|
+
- Support for new cds build task option `deploy-format`. Java apps may use this option instead of the corresponding global CDS config option.
|
|
35
|
+
- The `ExtensibilityService` serves an endpoint to retrieve a subdomain-specific JWT, which is used by `cds login`
|
|
36
|
+
- The endpoint `/-/cds/extensibility/push` now checks restrictions for new extensions. The configuration is added to the `cds.xt.ExtensibilityService`
|
|
37
|
+
```js
|
|
38
|
+
"requires": {
|
|
39
|
+
"cds.xt.ExtensibilityService": {
|
|
40
|
+
"element-prefix": ["Z_", "ZZ_"],
|
|
41
|
+
"namespace-blocklist": ["com.sap.", "sap."],
|
|
42
|
+
"extension-allowlist": [
|
|
43
|
+
{
|
|
44
|
+
"for": ["my.bookshop"],
|
|
45
|
+
"kind": "entity",
|
|
46
|
+
"new-fields": 2
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"for": ["CatalogService"],
|
|
50
|
+
"new-entities": 2
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
- `cds build` validates required service models `@sap/**` for MTX sidecar app and logs an ERROR if some couldn't be resolved.
|
|
57
|
+
- Configuration schema for many properties of the `cds` configuration block in `package.json` or `.cdsrc.json`, especially for `cds.requires...`
|
|
58
|
+
|
|
59
|
+
### Changed
|
|
60
|
+
|
|
61
|
+
- Streamlined calculation of the difference for `DELETE` queries using `req.diff()`
|
|
62
|
+
- Improved error messages for rest / new odata parser
|
|
63
|
+
- Adjust types for `SELECT.from` and `SELECT.one` to accept array classes as well
|
|
64
|
+
- No `"` added around search values in OData v2 e.g. Foo?search=name is passed through as is
|
|
65
|
+
- If an entity can not be read after write (e.g. insert only entity) no error is shown in the log
|
|
66
|
+
- Throw not supported error for pagination in `$expand`
|
|
67
|
+
|
|
68
|
+
### Fixed
|
|
69
|
+
|
|
70
|
+
- Wrong context in `tx.run(query)` when `query` is an array
|
|
71
|
+
- We now detect and ignore erroneous attempts to re-register framework-generated stubs as handlers for custom actions/functions.
|
|
72
|
+
- Emits with `persistent-outbox` also work with manual transactions
|
|
73
|
+
- You can now use `cds.ql` fluent API to query tables not in the model, but in database.
|
|
74
|
+
For example, within `cap/samples/bookshop` this works now:
|
|
75
|
+
```sql
|
|
76
|
+
await SELECT.from('sqlite_master')
|
|
77
|
+
await cds.read('sqlite_master')
|
|
78
|
+
```
|
|
79
|
+
Caveat: the following undocumented usage of unqualified names happened to work in the past.
|
|
80
|
+
But this was very fragile and caused lots of issues, and therefore was removed:
|
|
81
|
+
```sql
|
|
82
|
+
await SELECT.from('Books')
|
|
83
|
+
await cds.read('Books')
|
|
84
|
+
```
|
|
85
|
+
Always use qualified names, or reflected definitions instead:
|
|
86
|
+
```sql
|
|
87
|
+
const Books = 'sap.capire.bookshop.Books'
|
|
88
|
+
await SELECT.from(Books)
|
|
89
|
+
await cds.read(Books)
|
|
90
|
+
```
|
|
91
|
+
```sql
|
|
92
|
+
const {Books} = cds.entities ('sap.capire.bookshop')
|
|
93
|
+
await SELECT.from(Books)
|
|
94
|
+
await cds.read(Books)
|
|
95
|
+
```
|
|
96
|
+
- Wrong results for expand to many without `orderBy`
|
|
97
|
+
- `cds deploy` api endpoint regex for cli now ignores trailing version info in url
|
|
98
|
+
- Default values no longer overwrite payload values on fields of new drafts
|
|
99
|
+
- Unmanaged to-one navigation caused malformed SQL statement in draft
|
|
100
|
+
- `cds.compile.to.serviceinfo` fix failure to detect Java services if `odataV4.endpoint.path` or `odataV2.endpoint.path` missing in `cds` configuration in `application.yaml`
|
|
101
|
+
- Data type conversion did not work in some expand cases
|
|
102
|
+
- Failed connection to SAP HANA with no or malformed credentials was leading to credentials being written to the log
|
|
103
|
+
- `cds build` no longer fails with an error `no such file` if one of the following files has been defined in some `srv` subfolder - `package.json, package-lock.json, .cdsrc.json, .npmrc`
|
|
104
|
+
- Tar issue on Windows: 'The command line is too long'.
|
|
105
|
+
- `$search`: Lifecycle issue that causes an empty search result when the `$search` and `$expand` query options were combined
|
|
106
|
+
- Operator `IN` with Tagged Template String Literals e.g.:
|
|
107
|
+
```sql
|
|
108
|
+
SELECT.from(Object).where`userId IN ${aUserIDs}`
|
|
109
|
+
```
|
|
110
|
+
- `cds build` now uses a closed version range in the node engines version of the deployed application's `package.json`
|
|
111
|
+
- `cds build` no longer generates EDMX files for services that aren't odata protocol enabled
|
|
112
|
+
- `cds deploy` handles orgs and spaces containing commas correctly
|
|
113
|
+
- Incorrect decoding of special characters when reading data of type `cds.LargeString` from SAP HANA using `hdb@^0.19.5` driver
|
|
114
|
+
- The payload is added to the delete request in rest adapter as req.data
|
|
115
|
+
|
|
116
|
+
## Version 6.0.4 - 2022-07-20
|
|
117
|
+
|
|
118
|
+
### Fixed
|
|
119
|
+
|
|
120
|
+
- Local mocking of external services using `cds watch`
|
|
121
|
+
|
|
122
|
+
## Version 6.0.3 - 2022-07-14
|
|
123
|
+
|
|
124
|
+
### Changed
|
|
125
|
+
|
|
126
|
+
- On Business Application Studio, `@sap/cds` now rejects starting on Node 12, as it does locally. This avoids cryptic follow-up errors.
|
|
127
|
+
|
|
128
|
+
### Fixed
|
|
129
|
+
|
|
130
|
+
- Generic handlers for draft-related operations will trigger a READ event afterwards
|
|
131
|
+
- `file-based-messaging` only watches the file when at least one handler is registered
|
|
132
|
+
- `--vap-file` parameter of `cds deploy` is available again
|
|
133
|
+
- `cds build` no longer throws an error if `@sap/cds-mtx` library (classic MTX) isn't installed locally.
|
|
134
|
+
- `cds.spawn` no longer tries to reuse a transaction
|
|
135
|
+
- Custom query parameter caused bad request on certain characters in rest adapter
|
|
136
|
+
- `cds-ts` no longer fails with an `ERR_UNKNOWN_FILE_EXTENSION` error
|
|
137
|
+
- Timeouts when sending string payloads to remote services
|
|
138
|
+
- `cds.context.http` for `$batch` using atomicity groups
|
|
139
|
+
|
|
7
140
|
## Version 6.0.2 - 2022-07-06
|
|
8
141
|
|
|
9
142
|
### Fixed
|
|
10
143
|
|
|
11
144
|
- Jest tests do not fail any longer because of logs during app shutdown
|
|
12
|
-
- `cds build` now uses correct `mtx/sidecar` context. This avoids redundant `cds-mtxs` npm dependency for Java projects.
|
|
145
|
+
- `cds build` now uses correct `mtx/sidecar` context. This avoids redundant `cds-mtxs` npm dependency for Java projects.
|
|
13
146
|
|
|
14
147
|
## Version 6.0.1 - 2022-07-05
|
|
15
148
|
|
|
16
149
|
### Added
|
|
150
|
+
|
|
17
151
|
- Config option `cds.env.server.port` allows to configure the port to use (in addition to `process.env.PORT` and CLI option `--port`)
|
|
18
152
|
|
|
153
|
+
### Changed
|
|
154
|
+
|
|
155
|
+
- Plugins cannot be loaded as ES modules, but need to remain CommonJS modules
|
|
156
|
+
|
|
19
157
|
### Fixed
|
|
20
158
|
|
|
21
159
|
- Removed debug log about shutdown from `cds serve`
|
|
22
160
|
- Hiding timeout error in production mode
|
|
23
161
|
|
|
24
|
-
### Changed
|
|
25
|
-
|
|
26
|
-
- Plugins cannot be loaded as ES modules, but need to remain CommonJS modules
|
|
27
|
-
|
|
28
162
|
## Version 6.0.0 - 2022-06-30
|
|
29
163
|
|
|
30
164
|
### Added
|
|
@@ -71,7 +205,7 @@
|
|
|
71
205
|
- Support for `FOR SHARE LOCK` on SAP HANA to acquire shared locks on the queried records so that the locked records
|
|
72
206
|
stay intact until the transaction is committed or rolled back.
|
|
73
207
|
- Consistent error information for remote batch requests
|
|
74
|
-
- `cds.env` now supports expanding scalar `cds.requires` entries from `cds.requires.kinds`as follows:
|
|
208
|
+
- `cds.env` now supports expanding scalar `cds.requires` entries from `cds.requires.kinds` as follows:
|
|
75
209
|
```jsonc
|
|
76
210
|
{ "cds": {
|
|
77
211
|
"requires": {
|
|
@@ -90,23 +224,23 @@ stay intact until the transaction is committed or rolled back.
|
|
|
90
224
|
- Ordering by aggregated value for draft-enabled active entity
|
|
91
225
|
- `cds build` support for model provider service-based resource deployment.
|
|
92
226
|
- Remote service:
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
227
|
+
+ Conversion of OData V2 (`"kind": "odata-v2"`) function and action results to OData V4 format
|
|
228
|
+
+ Conversion of binary data in CQN queries to `base64url` in URL and payload
|
|
229
|
+
+ Key predicate is omitted for single-key entities in resulting URL (e.g. `GET /Foo(1)` instead of `GET /Foo(ID=1)`)
|
|
230
|
+
+ Support of views with parameters
|
|
97
231
|
- Add `@odata.mediaContentType` if selecting stream property
|
|
98
232
|
- Kubernetes service bindings: Support for servicebinding.io and SAP BTP Service Operator based bindings
|
|
99
233
|
- `cds build` copies an existing `.npmrc` file located in the root or srv folder of your project into the deployment folder (usually `gen/srv`). This allows for dedicated npm configuration in cloud environments. Can be switched off by cds build option `contentNpmrc`.
|
|
100
234
|
- `cds build` copies an existing `.cdsrc.json` file located in the root or srv folder of your project into the deployment folder (usually `gen/srv`). The effective CDS configuration is created from the `.cdsrc.json` and CDS configuration defined in the `package.json` file. Can be switched off by cds build option `contentCdsrcJson`.
|
|
101
235
|
- Beta OData URL to CQN parser (`cds.env.features.odata_new_parser = true`):
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
236
|
+
+ `@odata.context` is derived without using okra, not yet supported:
|
|
237
|
+
+ `$expand=*` query option
|
|
238
|
+
+ Support for actions and functions
|
|
239
|
+
+ Further `$apply` transformations supported
|
|
240
|
+
+ (nested) `concat` transformations
|
|
241
|
+
+ `orderBy` transformation
|
|
242
|
+
+ `top` & `skip` transformation
|
|
243
|
+
+ `identity` transformation
|
|
110
244
|
- Log `BEGIN`/`COMMIT`/`ROLLBACK` commands when using SAP HANA as the underlying database
|
|
111
245
|
- Binary data in payload is validated to be RFC-4648 and OData ABNF conformed
|
|
112
246
|
- Support multiple media (streaming) properties in one entity
|
|
@@ -116,7 +250,6 @@ stay intact until the transaction is committed or rolled back.
|
|
|
116
250
|
- $filter in $expand for remote services
|
|
117
251
|
- Mapping of aliases in $expand for remote services
|
|
118
252
|
|
|
119
|
-
|
|
120
253
|
### Changed
|
|
121
254
|
|
|
122
255
|
- `@sap/cds` can now be loaded from different install locations like any other module, i.e. `@require('@sap/cds')` will no longer return the same singleton instance.
|
|
@@ -170,6 +303,7 @@ Note that this is a breaking change for appliations that rely on error sanitizat
|
|
|
170
303
|
|
|
171
304
|
### Fixed
|
|
172
305
|
|
|
306
|
+
- We don't rely on `global.cds` anymore -> allows to load and correctly work with multiple versions of `cds`
|
|
173
307
|
- Improved shutdown for AMQP connections and file listeners
|
|
174
308
|
- Using `CQL` with a tagged template string `SELECT from Foo { null as boo }` throwed an exception.
|
|
175
309
|
- In case of `MULTIPLE_ERRORS` throw an `Error` instead of an object
|
package/apis/cds.d.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
+
|
|
2
|
+
type cds_facade = import('./core')
|
|
3
|
+
& import('./models')
|
|
4
|
+
& import('./connect')
|
|
5
|
+
& import('./serve')
|
|
6
|
+
& import('./ql').cds_ql
|
|
7
|
+
& import('./services').cds
|
|
8
|
+
& import('./services').QueryAPI
|
|
9
|
+
& import('./log')
|
|
10
|
+
|
|
1
11
|
declare global {
|
|
2
|
-
const cds :
|
|
3
|
-
& import ('./models')
|
|
4
|
-
& import ('./connect')
|
|
5
|
-
& import ('./serve')
|
|
6
|
-
& import ('./ql').cds_ql
|
|
7
|
-
& import ('./services').cds
|
|
8
|
-
& import ('./services').QueryAPI
|
|
12
|
+
const cds : cds_facade
|
|
9
13
|
class SELECT<T> extends cds.ql.SELECT<T>{}
|
|
10
14
|
class INSERT<T> extends cds.ql.INSERT<T>{}
|
|
11
15
|
class UPDATE<T> extends cds.ql.UPDATE<T>{}
|
package/apis/log.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns a trace logger for the given module if trace is switched on for it,
|
|
3
|
+
* otherwise returns null. All cds runtime packages use this method for their
|
|
4
|
+
* trace and debug output.
|
|
5
|
+
*
|
|
6
|
+
* @see [capire](https://cap.cloud.sap/docs/node.js/cds-log)
|
|
7
|
+
*
|
|
8
|
+
* By default this logger would prefix all output with '[sql] - '.
|
|
9
|
+
* You can change this by specifying another prefix in the options:
|
|
10
|
+
*
|
|
11
|
+
* const LOG = cds.log('sql|db',{ prefix:'cds.ql' })
|
|
12
|
+
*
|
|
13
|
+
* Call cds.log() for a given module again to dynamically change the log level
|
|
14
|
+
* of all formerly created loggers, for example:
|
|
15
|
+
*
|
|
16
|
+
* const LOG = cds.log('sql')
|
|
17
|
+
* LOG.info ('this will show, as default level is info')
|
|
18
|
+
* cds.log('sql','warn')
|
|
19
|
+
* LOG.info ('this will be suppressed now')
|
|
20
|
+
*
|
|
21
|
+
*/
|
|
22
|
+
export = cds
|
|
23
|
+
declare class cds {
|
|
24
|
+
log(name: string, options?: string | number | { level: number, prefix: string }): Logger
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
class Logger {
|
|
28
|
+
/**
|
|
29
|
+
* Formats a log outputs by returning an array of arguments which are passed to
|
|
30
|
+
* console.log() et al.
|
|
31
|
+
* You can assign custom formatters like that:
|
|
32
|
+
*
|
|
33
|
+
* cds.log.format = (module, level, ...args) => [ '[', module, ']', ...args ]
|
|
34
|
+
*/
|
|
35
|
+
format(module: string, level: number, args: any[]): any[]
|
|
36
|
+
trace(message?: any, ...optionalParams: any[]): void
|
|
37
|
+
debug(message?: any, ...optionalParams: any[]): void
|
|
38
|
+
log(message?: any, ...optionalParams: any[]): void
|
|
39
|
+
info(message?: any, ...optionalParams: any[]): void
|
|
40
|
+
warn(message?: any, ...optionalParams: any[]): void
|
|
41
|
+
error(message?: any, ...optionalParams: any[]): void
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
declare const levels = {
|
|
45
|
+
SILENT: 0, ERROR: 1, WARN: 2, INFO: 3, DEBUG: 4, TRACE: 5, SILLY: 5, VERBOSE: 5
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
declare const { ERROR, WARN, INFO, DEBUG, TRACE } = levels
|
package/apis/ql.d.ts
CHANGED
|
@@ -15,6 +15,31 @@ export class cds_ql {
|
|
|
15
15
|
ql:QL & ((context:object) => QL)
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
export type PK = number | string | object
|
|
19
|
+
|
|
20
|
+
// to support path expressions: https://pages.github.tools.sap/cap/docs/java/query-api#path-expressions
|
|
21
|
+
// `Book.title` == `Proxy<Book>.title()`
|
|
22
|
+
type Proxy<T> = {
|
|
23
|
+
[Key in keyof T]: () => Proxy<T[Key]>
|
|
24
|
+
} & {
|
|
25
|
+
/**
|
|
26
|
+
* Accesses any nested attribute based on a path:
|
|
27
|
+
* `X.get('a.b.c.d')`. Note that you will not receive
|
|
28
|
+
* proper typing after this call.
|
|
29
|
+
* To still have access to typed results, use
|
|
30
|
+
* `X.a().b().c().d()` instead.
|
|
31
|
+
*/
|
|
32
|
+
get: (path: string) => Proxy<unknown>
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// any class (not value) of array to represent plural types used in cds-typer.
|
|
36
|
+
// Mainly used as pattern match for SingularType
|
|
37
|
+
type ArrayClass = {new():Array<unknown>}
|
|
38
|
+
|
|
39
|
+
// concrete singular type.
|
|
40
|
+
// `SingularType<typeof Books>` == `Book`.
|
|
41
|
+
type SingularType<T extends ArrayClass> = InstanceType<T>[number]
|
|
42
|
+
|
|
18
43
|
declare class QL {
|
|
19
44
|
SELECT : typeof SELECT & ((...columns:string[]) => SELECT<any>) & ((columns:string[]) => SELECT<any>)
|
|
20
45
|
INSERT : typeof INSERT & ((...entries:object[]) => INSERT<any>) & ((entries:object[]) => INSERT<any>)
|
|
@@ -26,12 +51,14 @@ declare class QL {
|
|
|
26
51
|
|
|
27
52
|
// (new QL).SELECT.from('Foo').byKey(11).a
|
|
28
53
|
|
|
54
|
+
|
|
55
|
+
|
|
29
56
|
export class SELECT<T> extends ConstructedQuery {
|
|
30
57
|
static one : SELECT_one & { from: SELECT_one }
|
|
31
58
|
static distinct : typeof SELECT
|
|
32
59
|
static from : SELECT_from
|
|
33
|
-
from (entity: Definition | string, primaryKey? :
|
|
34
|
-
byKey (primaryKey? :
|
|
60
|
+
from (entity: Definition | string, primaryKey? : PK, projection? : (e:any)=>void) : this
|
|
61
|
+
byKey (primaryKey? : PK) : this
|
|
35
62
|
columns (projection:(e:T)=>void) : this
|
|
36
63
|
columns (...col:string[]) : this
|
|
37
64
|
where (predicate:object) : this
|
|
@@ -43,23 +70,53 @@ export class SELECT<T> extends ConstructedQuery {
|
|
|
43
70
|
groupBy (...expr : string[]) : this
|
|
44
71
|
orderBy (...expr : string[]) : this
|
|
45
72
|
limit (rows : number, offset? : number) : this
|
|
73
|
+
forSharedLock () : this
|
|
74
|
+
forUpdate () : this
|
|
46
75
|
SELECT : CQN.SELECT
|
|
47
76
|
}
|
|
48
77
|
|
|
49
78
|
type SELECT_one =
|
|
50
|
-
((entity: Definition | string, primaryKey? :
|
|
79
|
+
((entity: Definition | string, primaryKey? : PK, projection? : (e:any)=>void) => SELECT<any>)
|
|
80
|
+
|
|
81
|
+
// calling with class
|
|
82
|
+
& (<T extends ArrayClass>
|
|
83
|
+
(entityType: T)
|
|
84
|
+
=> SELECT<SingularType<T>> & Promise<SingularType<T>>)
|
|
85
|
+
&
|
|
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
|
+
|
|
51
95
|
& (<T> (entity: T[], projection? : (e:T)=>void) => SELECT<T> & Promise<T>)
|
|
52
|
-
& (<T> (entity: T[], primaryKey :
|
|
96
|
+
& (<T> (entity: T[], primaryKey : PK, projection? : (e:T)=>void) => SELECT<T> & Promise<T>)
|
|
53
97
|
& (<T> (entity: {new():T}, projection? : (e:T)=>void) => SELECT<T> & Promise<T>)
|
|
54
|
-
& (<T> (entity: {new():T}, primaryKey :
|
|
98
|
+
& (<T> (entity: {new():T}, primaryKey : PK, projection? : (e:T)=>void) => SELECT<T> & Promise<T>)
|
|
99
|
+
|
|
55
100
|
|
|
56
101
|
|
|
57
102
|
type SELECT_from =
|
|
58
|
-
|
|
103
|
+
// calling with class
|
|
104
|
+
(<T extends ArrayClass>
|
|
105
|
+
(entityType: T)
|
|
106
|
+
=> SELECT<SingularType<T>> & Promise<SingularType<T>>)
|
|
107
|
+
&
|
|
108
|
+
(<T extends ArrayClass>
|
|
109
|
+
(entityType: T, projection: (e: Proxy<SingularType<T>>) => void)
|
|
110
|
+
=> SELECT<SingularType<T>> & Promise<SingularType<T>>)
|
|
111
|
+
&
|
|
112
|
+
(<T extends ArrayClass>
|
|
113
|
+
(entityType: T, primaryKey : PK, projection: (e: Proxy<SingularType<T>>) => void)
|
|
114
|
+
=> SELECT<SingularType<T>> & Promise<SingularType<T>>)
|
|
115
|
+
// calling with definition
|
|
116
|
+
& ((entity: Definition | string, primaryKey? : PK, projection? : (e:any)=>void) => SELECT<any>)
|
|
117
|
+
// calling with concrete list
|
|
59
118
|
& (<T> (entity: T[], projection? : (e:T)=>void) => SELECT<T> & Promise<T[]>)
|
|
60
|
-
& (<T> (entity: T[], primaryKey :
|
|
61
|
-
& (<T> (entity: {new():T}, projection? : (e:T)=>void) => SELECT<T> & Promise<T[]>)
|
|
62
|
-
& (<T> (entity: {new():T}, primaryKey : number | string | object, projection? : (e:T)=>void) => SELECT<T> & Promise<T>)
|
|
119
|
+
& (<T> (entity: T[], primaryKey : PK, projection? : (e:T)=>void) => SELECT<T> & Promise<T>)
|
|
63
120
|
|
|
64
121
|
|
|
65
122
|
export class INSERT<T> extends ConstructedQuery {
|
|
@@ -76,8 +133,8 @@ export class INSERT<T> extends ConstructedQuery {
|
|
|
76
133
|
}
|
|
77
134
|
|
|
78
135
|
export class DELETE<T> extends ConstructedQuery {
|
|
79
|
-
static from (entity : Definition | string, primaryKey? :
|
|
80
|
-
byKey (primaryKey? :
|
|
136
|
+
static from (entity : Definition | string, primaryKey? : PK) : DELETE<any>
|
|
137
|
+
byKey (primaryKey? : PK) : this
|
|
81
138
|
where (predicate:object) : this
|
|
82
139
|
where (...expr : any[]) : this
|
|
83
140
|
and (predicate:object) : this
|
|
@@ -86,10 +143,10 @@ export class DELETE<T> extends ConstructedQuery {
|
|
|
86
143
|
}
|
|
87
144
|
|
|
88
145
|
export class UPDATE<T> extends ConstructedQuery {
|
|
89
|
-
static entity (entity : Definition | string, primaryKey? :
|
|
90
|
-
static entity <T> (entity:Constructable<T>, primaryKey? :
|
|
91
|
-
static entity <T> (entity:T, primaryKey? :
|
|
92
|
-
byKey (primaryKey? :
|
|
146
|
+
static entity (entity : Definition | string, primaryKey? : PK) : UPDATE<any>
|
|
147
|
+
static entity <T> (entity:Constructable<T>, primaryKey? : PK) : UPDATE<T>
|
|
148
|
+
static entity <T> (entity:T, primaryKey? : PK) : UPDATE<T>
|
|
149
|
+
byKey (primaryKey? : PK) : this
|
|
93
150
|
// with (block: (e:T)=>void) : this
|
|
94
151
|
// set (block: (e:T)=>void) : this
|
|
95
152
|
set (data:object) : this
|
|
@@ -187,9 +187,8 @@ class BuildTaskHandler {
|
|
|
187
187
|
return null
|
|
188
188
|
}
|
|
189
189
|
this._logger._debug && this._logger.debug(`model: ${relativePaths(this._buildOptions.root, files).join(", ")}`)
|
|
190
|
-
const options = { messages: this._messages }
|
|
191
190
|
// $location paths are relative to current working dir by default - make sure a given project root folder is taken
|
|
192
|
-
options
|
|
191
|
+
const options = { ...this.options(), cwd: this._buildOptions.root }
|
|
193
192
|
|
|
194
193
|
const model = await this._cds.load(files, options)
|
|
195
194
|
if (!model) {
|
|
@@ -198,6 +197,10 @@ class BuildTaskHandler {
|
|
|
198
197
|
return model
|
|
199
198
|
}
|
|
200
199
|
|
|
200
|
+
options() {
|
|
201
|
+
return { messages: this._messages }
|
|
202
|
+
}
|
|
203
|
+
|
|
201
204
|
/**
|
|
202
205
|
* Adds the given fully qualified file path to the list of files that are written by this build task.
|
|
203
206
|
* @param {string} filePath
|
package/bin/build/constants.js
CHANGED
|
@@ -14,7 +14,8 @@ exports.BUILD_TASK_HANA = "hana"
|
|
|
14
14
|
exports.BUILD_TASK_FIORI = "fiori"
|
|
15
15
|
exports.BUILD_TASK_MTX = "mtx"
|
|
16
16
|
exports.BUILD_TASK_MTX_SIDECAR = "mtx-sidecar"
|
|
17
|
-
exports.
|
|
17
|
+
exports.BUILD_TASK_MTX_EXTENSION = "mtx-extension"
|
|
18
|
+
exports.BUILD_TASKS = [this.BUILD_TASK_JAVA, this.BUILD_TASK_JAVA_CF, this.BUILD_TASK_NODEJS, this.BUILD_TASK_NODE_CF, this.BUILD_TASK_HANA, this.BUILD_TASK_FIORI, this.BUILD_TASK_MTX, this.BUILD_TASK_MTX_SIDECAR, this.BUILD_TASK_MTX_EXTENSION]
|
|
18
19
|
|
|
19
20
|
exports.ODATA_VERSION = "odata.version"
|
|
20
21
|
exports.ODATA_VERSION_V2 = "v2"
|
|
@@ -44,6 +45,7 @@ exports.CSV_FILE_DETECTION = "csvFileDetection" // detect CSV files
|
|
|
44
45
|
exports.FOLDER_GEN = "gen"
|
|
45
46
|
exports.FILE_EXT_CDS = ".cds"
|
|
46
47
|
exports.MTX_SIDECAR_FOLDER = "mtx/sidecar" // default name of the mtx sidecar folder
|
|
48
|
+
exports.DEFAULT_CSN_FILE_NAME = "csn.json"
|
|
47
49
|
|
|
48
50
|
exports.CDS_CONFIG_PATH_SEP = "/"
|
|
49
51
|
exports.SKIP_ASSERT_COMPILER_V2 = "skip-assert-compiler-v2"
|
|
@@ -59,3 +61,4 @@ exports.LOG_LEVEL_DEBUG = "debug"
|
|
|
59
61
|
exports.LOG_LEVELS = [exports.LOG_LEVEL_ERROR, exports.LOG_LEVEL_WARN, exports.LOG_LEVEL_INFO, exports.LOG_LEVEL_DEBUG]
|
|
60
62
|
exports.LOG_MODULE_NAMES = "cds|build"
|
|
61
63
|
exports.OVERRIDE_METHOD_MSG = "Must override method"
|
|
64
|
+
exports.SEMVER_REGEX = /^(\D*)(\d+\.)?(\d+\.)?(\*|\d+)/
|
|
@@ -5,16 +5,21 @@ const { BUILD_OPTION_OUTPUT_MODE, OUTPUT_MODE_RESULT_ONLY } = require('../consta
|
|
|
5
5
|
class BuildTaskHandlerEdmx extends BuildTaskHandlerFeatureToggles {
|
|
6
6
|
async compileToEdmx(model, edmxDest, compileOptions = {}) { // NOSONAR
|
|
7
7
|
const promises = []
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
// generate edmx for services only that have the odata protocol
|
|
10
|
+
const serviceNames = this.cds.reflect(model).services
|
|
11
|
+
.filter(service => this._isOdataProtocol(service))
|
|
12
|
+
.map(service => service.name)
|
|
9
13
|
|
|
10
14
|
// TODO mtx build_helper tests currently expects this, strange...
|
|
11
15
|
this._result.languages.add('')
|
|
12
16
|
|
|
13
17
|
// new compile impl is throwing error in case no services exist!
|
|
14
|
-
if (
|
|
18
|
+
if (serviceNames.length > 0) {
|
|
15
19
|
const options = {
|
|
16
20
|
...this._options4edmx(),
|
|
17
|
-
...compileOptions
|
|
21
|
+
...compileOptions,
|
|
22
|
+
serviceNames
|
|
18
23
|
}
|
|
19
24
|
this.logger._debug && this.logger.debug(`compiling edmx files using OData version ${options.version}`)
|
|
20
25
|
|
|
@@ -45,42 +50,9 @@ class BuildTaskHandlerEdmx extends BuildTaskHandlerFeatureToggles {
|
|
|
45
50
|
return Promise.all(promises)
|
|
46
51
|
}
|
|
47
52
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
* @param {string} bundleDest
|
|
52
|
-
*/
|
|
53
|
-
async collectLanguageBundles(model, bundleDest, saveResult = true) {
|
|
54
|
-
// collect effective i18n properties...
|
|
55
|
-
let bundles = {}
|
|
56
|
-
const bundleGenerator = this.cds.localize.bundles4(model)
|
|
57
|
-
if (bundleGenerator && bundleGenerator[Symbol.iterator]) {
|
|
58
|
-
for (let [locale, bundle] of bundleGenerator) {
|
|
59
|
-
// fallback bundle has the name ""
|
|
60
|
-
if (typeof locale === 'string') {
|
|
61
|
-
bundles[locale] = bundle
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// omit bundles in case the fallback bundle is the only existing entry
|
|
67
|
-
const keys = Object.keys(bundles)
|
|
68
|
-
if (keys.length === 1 && keys[0] === "" && Object.keys(bundles[keys[0]]).length === 0) {
|
|
69
|
-
bundles = {}
|
|
70
|
-
}
|
|
71
|
-
// copied from ../compile/i18n.js
|
|
72
|
-
const { folders = ['i18n'], file = 'i18n' } = this.env.i18n
|
|
73
|
-
|
|
74
|
-
// bundleDest might be null
|
|
75
|
-
if (bundleDest && Object.keys(bundles).length > 0) {
|
|
76
|
-
if (!this.hasBuildOption(BUILD_OPTION_OUTPUT_MODE, OUTPUT_MODE_RESULT_ONLY)) {
|
|
77
|
-
await this.write(bundles).to(path.join(bundleDest, folders[0], file + '.json'))
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
if (saveResult) {
|
|
81
|
-
this._result.languageBundles = bundles
|
|
82
|
-
}
|
|
83
|
-
return bundles
|
|
53
|
+
_isOdataProtocol(service) {
|
|
54
|
+
const { _protocol4Service } = this.cds.service.adapters
|
|
55
|
+
return /^odata/.test(_protocol4Service(service))
|
|
84
56
|
}
|
|
85
57
|
|
|
86
58
|
_options4odata() {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
2
|
const path = require('path')
|
|
3
|
-
const {
|
|
3
|
+
const { DEFAULT_CSN_FILE_NAME } = require('../constants')
|
|
4
4
|
const BuildTaskHandlerInternal = require('./buildTaskHandlerInternal')
|
|
5
5
|
|
|
6
6
|
class FeatureToggleBuilder extends BuildTaskHandlerInternal {
|
|
@@ -31,7 +31,10 @@ class FeatureToggleBuilder extends BuildTaskHandlerInternal {
|
|
|
31
31
|
dictionary.base = csn
|
|
32
32
|
}
|
|
33
33
|
// preserve @location as @source properties
|
|
34
|
-
await this.compileToJson(dictionary.base, destBase)
|
|
34
|
+
const csnStr = await this.compileToJson(dictionary.base, path.join(destBase, DEFAULT_CSN_FILE_NAME))
|
|
35
|
+
const csnModel = JSON.parse(csnStr)
|
|
36
|
+
csnModel.meta = csn.meta
|
|
37
|
+
this._result.csn = csnModel
|
|
35
38
|
|
|
36
39
|
if (sources.features) {
|
|
37
40
|
dictionary.features = await this._compileFeatures(sources.features, destBase, destFts)
|
|
@@ -41,13 +44,17 @@ class FeatureToggleBuilder extends BuildTaskHandlerInternal {
|
|
|
41
44
|
|
|
42
45
|
async collectAllLanguageBundles(dictionary, paths, destBase, destFts) {
|
|
43
46
|
// create language bundle for base model
|
|
44
|
-
await this.collectLanguageBundles(dictionary.base, destBase)
|
|
47
|
+
const i18n = await this.collectLanguageBundles(dictionary.base, destBase)
|
|
48
|
+
if (i18n) {
|
|
49
|
+
this._result.languageBundles = i18n.bundles
|
|
50
|
+
}
|
|
51
|
+
|
|
45
52
|
if (dictionary.features) {
|
|
46
53
|
// create language bundles for all features
|
|
47
54
|
for (const ftName in dictionary.features) {
|
|
48
55
|
// attach the sources information for i18n location reference
|
|
49
56
|
dictionary.features[ftName]['$sources'] = paths.features[ftName]
|
|
50
|
-
await this.collectLanguageBundles(dictionary.features[ftName], path.join(destFts, this.ftsName, ftName)
|
|
57
|
+
await this.collectLanguageBundles(dictionary.features[ftName], path.join(destFts, this.ftsName, ftName))
|
|
51
58
|
}
|
|
52
59
|
}
|
|
53
60
|
}
|
|
@@ -87,32 +94,6 @@ class FeatureToggleBuilder extends BuildTaskHandlerInternal {
|
|
|
87
94
|
return paths
|
|
88
95
|
}
|
|
89
96
|
|
|
90
|
-
async compileToJson(model, csnDest, saveResult = true) {
|
|
91
|
-
// This will als add a @source prop containing the relative path to the origin .cds source file
|
|
92
|
-
// and a parsed _where clause for @restrict.{grant,where} annotations.
|
|
93
|
-
// The @source annotation is required for correct custom handler resolution if no @impl annotation has been defined as
|
|
94
|
-
// custom service handler implementations are relative to the origin .cds source files.
|
|
95
|
-
// For staging builds (task.src !== task.dest) the csn.json file that is served at runtime is copied into a corresponding srv subfolder.
|
|
96
|
-
// As a consequence the src folder name has to be included in the @source file name while for inplace builds (task.src === task.dest) this is not the case.
|
|
97
|
-
// This ensures that the paths are relative to the cwd when executing cds run.
|
|
98
|
-
const jsonOptions = {
|
|
99
|
-
cwd: this.buildOptions.root,
|
|
100
|
-
src: this.task.src === this.task.dest ? this.task.src : this.buildOptions.root
|
|
101
|
-
}
|
|
102
|
-
const csnStr = this.cds.compile.to.json(model, jsonOptions)
|
|
103
|
-
const csn = JSON.parse(csnStr)
|
|
104
|
-
if (saveResult) {
|
|
105
|
-
this._result.csn = csn
|
|
106
|
-
this._result.csn.meta = model.meta
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// csnDest might be null
|
|
110
|
-
if (csnDest && !this.hasBuildOption(BUILD_OPTION_OUTPUT_MODE, OUTPUT_MODE_RESULT_ONLY)) {
|
|
111
|
-
await this.write(csnStr).to(path.join(csnDest, 'csn.json'))
|
|
112
|
-
}
|
|
113
|
-
return csn
|
|
114
|
-
}
|
|
115
|
-
|
|
116
97
|
async _compileFeatures(ftsPaths, destBase, destFts) {
|
|
117
98
|
if (!ftsPaths) {
|
|
118
99
|
return
|
|
@@ -127,10 +108,10 @@ class FeatureToggleBuilder extends BuildTaskHandlerInternal {
|
|
|
127
108
|
|
|
128
109
|
// replace require paths by base model path to ensure precedence of feature annos
|
|
129
110
|
// see https://pages.github.tools.sap/cap/docs/cds/compiler-messages#anno-duplicate-unrelated-layer
|
|
130
|
-
ftCsn.requires = [path.join('../..', srvFolder,
|
|
111
|
+
ftCsn.requires = [path.join('../..', srvFolder, DEFAULT_CSN_FILE_NAME)]
|
|
131
112
|
|
|
132
113
|
const ftPath = path.join(destFts, this.ftsName, ftName)
|
|
133
|
-
await this.compileToJson(ftCsn, ftPath,
|
|
114
|
+
await this.compileToJson(ftCsn, path.join(ftPath, DEFAULT_CSN_FILE_NAME))
|
|
134
115
|
await this._validateFeature(ftPath)
|
|
135
116
|
features[ftName] = ftCsn
|
|
136
117
|
}
|