@sap/cds 6.6.2 → 6.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +72 -2
- package/README.md +1 -1
- package/apis/connect.d.ts +11 -4
- package/apis/core.d.ts +1 -1
- package/apis/csn.d.ts +1 -0
- package/apis/internal/inference.d.ts +15 -2
- package/apis/log.d.ts +10 -0
- package/apis/serve.d.ts +4 -9
- package/apis/services.d.ts +86 -19
- package/bin/build/buildTaskEngine.js +16 -42
- package/bin/build/constants.js +4 -2
- package/bin/build/provider/buildTaskProviderInternal.js +117 -85
- package/bin/build/provider/hana/index.js +6 -1
- package/bin/build/provider/mtx-extension/index.js +74 -34
- package/bin/build/provider/mtx-sidecar/index.js +3 -3
- package/bin/build/provider/nodejs/index.js +2 -2
- package/bin/build/util.js +63 -14
- package/bin/cds-serve.js +6 -0
- package/bin/cds.js +22 -4
- package/bin/deploy/to-hana/cfUtil.js +15 -1
- package/bin/mtx/in-cds.js +2 -9
- package/bin/plugins.js +31 -0
- package/bin/serve.js +12 -12
- package/lib/compile/etc/_localized.js +1 -1
- package/lib/compile/for/lean_drafts.js +23 -6
- package/lib/compile/for/nodejs.js +4 -1
- package/lib/compile/load.js +4 -2
- package/lib/core/index.js +35 -15
- package/lib/dbs/cds-deploy.js +129 -133
- package/lib/env/cds-env.js +25 -17
- package/lib/env/cds-requires.js +10 -40
- package/lib/env/compat.js +12 -0
- package/lib/env/defaults.js +17 -9
- package/lib/env/plugins.js +29 -0
- package/lib/env/schemas/cds-rc.json +14 -0
- package/lib/index.js +3 -0
- package/lib/log/cds-log.js +7 -4
- package/lib/ql/CREATE.js +1 -1
- package/lib/ql/DELETE.js +1 -1
- package/lib/ql/DROP.js +3 -3
- package/lib/ql/INSERT.js +1 -1
- package/lib/ql/Query.js +14 -6
- package/lib/ql/SELECT.js +8 -2
- package/lib/ql/UPDATE.js +1 -1
- package/lib/ql/Whereable.js +1 -1
- package/lib/ql/cds-ql.js +1 -9
- package/lib/req/cds-context.js +1 -4
- package/lib/req/request.js +63 -2
- package/lib/req/response.js +3 -2
- package/lib/srv/bindings.js +69 -71
- package/lib/srv/cds-connect.js +4 -1
- package/lib/srv/cds-serve.js +4 -0
- package/lib/srv/middlewares/index.js +37 -6
- package/lib/srv/protocols/_legacy.js +1 -1
- package/lib/srv/protocols/index.js +1 -1
- package/lib/srv/srv-api.js +4 -6
- package/lib/srv/srv-dispatch.js +4 -3
- package/lib/srv/srv-handlers.js +1 -1
- package/lib/srv/srv-methods.js +8 -2
- package/lib/utils/cds-test.js +4 -1
- package/libx/_runtime/audit/Service.js +8 -9
- package/libx/_runtime/audit/generic/personal/index.js +1 -1
- package/libx/_runtime/audit/generic/personal/utils.js +1 -1
- package/libx/_runtime/audit/utils/v2.js +17 -20
- package/libx/_runtime/auth/strategies/mock.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +2 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/delete.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +12 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +1 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/readToCQN.js +5 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/metaInfo.js +4 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/oDataConfiguration.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +1 -1
- package/libx/_runtime/cds-services/services/Service.js +28 -1
- package/libx/_runtime/cds-services/util/assert.js +41 -65
- package/libx/_runtime/common/code-ext/WorkerPool.js +90 -0
- package/libx/_runtime/common/code-ext/WorkerReq.js +0 -4
- package/libx/_runtime/common/code-ext/execute.js +28 -18
- package/libx/_runtime/common/code-ext/handlers.js +5 -4
- package/libx/_runtime/common/code-ext/worker.js +45 -3
- package/libx/_runtime/common/code-ext/workerQueryExecutor.js +8 -7
- package/libx/_runtime/common/composition/delete.js +1 -1
- package/libx/_runtime/common/composition/update.js +3 -5
- package/libx/_runtime/common/generic/auth/expand.js +1 -1
- package/libx/_runtime/common/generic/auth/readOnly.js +5 -4
- package/libx/_runtime/common/generic/auth/restrict.js +7 -2
- package/libx/_runtime/common/generic/auth/utils.js +5 -2
- package/libx/_runtime/common/generic/crud.js +12 -1
- package/libx/_runtime/common/generic/etag.js +11 -3
- package/libx/_runtime/common/generic/input.js +8 -6
- package/libx/_runtime/common/generic/paging.js +25 -8
- package/libx/_runtime/common/generic/put.js +1 -1
- package/libx/_runtime/common/generic/sorting.js +0 -1
- package/libx/_runtime/common/i18n/messages.properties +1 -0
- package/libx/_runtime/common/utils/cqn.js +5 -1
- package/libx/_runtime/common/utils/cqn2cqn4sql.js +3 -3
- package/libx/_runtime/common/utils/resolveView.js +14 -10
- package/libx/_runtime/common/utils/rewriteAsterisks.js +2 -3
- package/libx/_runtime/common/utils/templateProcessor.js +15 -17
- package/libx/_runtime/common/utils/templateProcessorPathSerializer.js +18 -6
- package/libx/_runtime/db/Service.js +1 -0
- package/libx/_runtime/db/data-conversion/post-processing.js +0 -18
- package/libx/_runtime/db/expand/expand-v2.js +2 -2
- package/libx/_runtime/db/expand/rawToExpanded.js +6 -6
- package/libx/_runtime/db/generic/integrity.js +1 -1
- package/libx/_runtime/db/utils/columns.js +5 -5
- package/libx/_runtime/fiori/generic/activate.js +3 -3
- package/libx/_runtime/fiori/generic/edit.js +1 -1
- package/libx/_runtime/fiori/generic/new.js +4 -0
- package/libx/_runtime/fiori/lean-draft.js +178 -68
- package/libx/_runtime/hana/execute.js +3 -1
- package/libx/_runtime/hana/pool.js +10 -2
- package/libx/_runtime/hana/search2cqn4sql.js +1 -1
- package/libx/_runtime/messaging/common-utils/AMQPClient.js +6 -1
- package/libx/_runtime/messaging/enterprise-messaging.js +1 -0
- package/libx/_runtime/remote/Service.js +16 -13
- package/libx/_runtime/remote/utils/client.js +6 -1
- package/libx/_runtime/sqlite/Service.js +5 -59
- package/libx/_runtime/sqlite/convertDraftAdminPathExpression.js +1 -0
- package/libx/_runtime/sqlite/customBuilder/CustomUpsertBuilder.js +2 -2
- package/libx/_runtime/sqlite/execute.js +3 -1
- package/libx/_runtime/types/api.js +12 -3
- package/libx/odata/afterburner.js +38 -2
- package/libx/odata/cqn2odata.js +3 -2
- package/libx/odata/grammar.pegjs +5 -3
- package/libx/odata/parser.js +1 -1
- package/libx/odata/utils.js +1 -1
- package/libx/rest/RestAdapter.js +1 -1
- package/libx/rest/RestRequest.js +1 -0
- package/package.json +5 -2
- package/libx/_runtime/common/code-ext/workerQuery.js +0 -45
- package/libx/_runtime/common/constants/limit.js +0 -12
- package/libx/_runtime/common/utils/page.js +0 -39
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,77 @@
|
|
|
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.7.1 - 2023-04-14
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Calling a parameterized view without params error now results in the status code 400 with an improved error message.
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- cds build error CreateListFromArrayLike
|
|
16
|
+
- Disabling of arbitrary user config in mock auth config using `"users": { "*": false }`
|
|
17
|
+
- Various fixes for `cds.fiori.lean_draft`
|
|
18
|
+
- User attributes that look like numbers are quoted in SQL clause for `@restrict`
|
|
19
|
+
|
|
20
|
+
## Version 6.7.0 - 2023-03-28
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- Config `cds.ql.quirks_mode` as a compatibility flag to still support behaviours which are undocumented, or even against the specifications, for example CQN:
|
|
25
|
+
```js
|
|
26
|
+
let q = INSERT.into('Books')
|
|
27
|
+
//> According to CQN spec should return:
|
|
28
|
+
{SELECT:{from:{ref:['Books']}}}
|
|
29
|
+
//> But today returns:
|
|
30
|
+
{SELECT:{from:'Books'}}
|
|
31
|
+
```
|
|
32
|
+
The default in cds6 is `true` → to be changed to `false` with cds7.
|
|
33
|
+
- `cds build` now checks extension point restrictions defined by the SaaS app provider. `cds build` fails if any restrictions are violated.
|
|
34
|
+
- Typings for `cds.spawn()`
|
|
35
|
+
- Typings for `entity.drafts`
|
|
36
|
+
- Typings for winston logger
|
|
37
|
+
- Typings for `service.on`, `service.before`, and `service.after` for actions and CRUD events
|
|
38
|
+
- CLI command `cds env` now allows property paths with `/` instead of `.`, which allows usages like that:
|
|
39
|
+
```sh
|
|
40
|
+
cds env requires/cds.xt.ModelProviderService
|
|
41
|
+
```
|
|
42
|
+
- `cds.env` now allows to statically set/add profiles via `cds.profile` and `cds.profiles` in package.json.
|
|
43
|
+
- `cds.env` now also supports using profiles in definitions of presets, i.e., in `cds.requires.kinds`.
|
|
44
|
+
- `cds deploy` prints a warning when using Cloud Foundry client version less than 8.
|
|
45
|
+
- `req.subject` to conveniently operate on the subjects targeted by the request. Example usage:
|
|
46
|
+
SELECT.one.from(req.subject) //> returns single
|
|
47
|
+
SELECT.from(req.subject) //> returns array
|
|
48
|
+
UPDATE(req.subject) //> updates one or many
|
|
49
|
+
DELETE(req.subject) //> deletes one or many
|
|
50
|
+
- `cds-serve` as a future replacement for `cds serve` in npm scripts. Applications can adopt this now to ease the transition to the next major version.
|
|
51
|
+
|
|
52
|
+
### Changed
|
|
53
|
+
|
|
54
|
+
- `cds.log().trace()` now logs stack traces in `DEBUG` level, before that was on `TRACE`/`SILLY` level only
|
|
55
|
+
- Plain SQL queries now have `req.event === undefined`, formerly this had non-deterministic values.
|
|
56
|
+
- Plain SQL queries don't allow to register custom handlers, other than for event `'*'`.
|
|
57
|
+
- Plain SQL queries are only supported on database services, not on application services.
|
|
58
|
+
- CQN representation of `columns=*` is not allowed anymore, instead `columns=['*']` should be used. This also applies to expand.
|
|
59
|
+
- Only draft roots can be created via direct, non-navigation OData `POST` requests.
|
|
60
|
+
- Flag `cds.features.fiori_preview` changed to `cds.fiori.preview`. The old flag still works as well.
|
|
61
|
+
- Flag `cds.features.fiori_routes` changed to `cds.fiori.routes`. The old flag still works as well.
|
|
62
|
+
|
|
63
|
+
### Fixed
|
|
64
|
+
|
|
65
|
+
- Proper handling of `IsActiveEntity` in error paths
|
|
66
|
+
- For cloudevents using AMQP, the type is set to `application/cloudevents+json`
|
|
67
|
+
- Use `message` property in typings.
|
|
68
|
+
- Typings for `cds.on('bootstrap', app => {app.use(...)`
|
|
69
|
+
- Return types for `User` and `delete` in typescript
|
|
70
|
+
- Typings for connect options
|
|
71
|
+
- Typings for `req.error`
|
|
72
|
+
- Deployment in sidecar
|
|
73
|
+
- Error with restricting an entity and request it with $apply in combination with aggregate
|
|
74
|
+
- Combined usage of `$skiptoken` and `$skip`
|
|
75
|
+
- Error `package.json file is missing` in mtx extension builds
|
|
76
|
+
- CLI commands w/ unknown arguments (`cds --foo`) clearly fail again with a proper error message
|
|
77
|
+
|
|
7
78
|
## Version 6.6.2 - 2023-03-17
|
|
8
79
|
|
|
9
80
|
### Fixed
|
|
@@ -29,15 +100,14 @@
|
|
|
29
100
|
## Version 6.6.0 - 2023-02-27
|
|
30
101
|
|
|
31
102
|
### Added
|
|
32
|
-
|
|
33
103
|
- Improved error handling for `cds build` if the SaaS base model is missing in an extension project.
|
|
34
104
|
- Support for reliable paging using `$skiptoken`. Can be activated via `cds.query.limit.reliablePaging = true`
|
|
105
|
+
- Built-in models are now added to existing model options of custom build tasks.
|
|
35
106
|
|
|
36
107
|
### Changed
|
|
37
108
|
|
|
38
109
|
- `cds.serve(ServiceName)` (and `cds serve -s ServiceName`) now exactly serve services with the given names. Previously, all services that ended with the given name were served as well, e.g. `MyServiceName` and `ServiceName`, which might be problematic for applications that bootstrap services one by one.
|
|
39
110
|
- Optimize `@cds.persistence.journal` filtering for `last-dev` CSN file.
|
|
40
|
-
- `process.exit()` is no longer called during server shutdown, so that other/custom exit handlers get a chance to execute.
|
|
41
111
|
|
|
42
112
|
### Fixed
|
|
43
113
|
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ The API package for the [SAP Cloud Application Programming Model (CAP)](https://
|
|
|
4
4
|
|
|
5
5
|
See the [API documentation](https://cap.cloud.sap/docs/node.js/api) for more details.
|
|
6
6
|
|
|
7
|
-
## How to Obtain Support
|
|
7
|
+
## How to Obtain Support
|
|
8
8
|
|
|
9
9
|
In case you find a bug, please report an [incident](https://cap.cloud.sap/docs/resources/#reporting-incidents) on SAP Support Portal.
|
|
10
10
|
|
package/apis/connect.d.ts
CHANGED
|
@@ -7,9 +7,15 @@ declare class cds {
|
|
|
7
7
|
connect : {
|
|
8
8
|
/**
|
|
9
9
|
* Connects to a specific datasource.
|
|
10
|
-
* @see [capire](https://cap.cloud.sap/docs/node.js/
|
|
10
|
+
* @see [capire](https://cap.cloud.sap/docs/node.js/cds-connect#cds-connect-to)
|
|
11
11
|
*/
|
|
12
|
-
to (datasource
|
|
12
|
+
to (datasource: string, options?: ConnectOptions) : Promise<Service>
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Connects to a specific datasource via options.
|
|
16
|
+
* @see [capire](https://cap.cloud.sap/docs/node.js/cds-connect#cds-connect-to)
|
|
17
|
+
*/
|
|
18
|
+
to (options: ConnectOptions) : Promise<Service>
|
|
13
19
|
|
|
14
20
|
/**
|
|
15
21
|
* Connects the primary datasource.
|
|
@@ -25,9 +31,10 @@ declare class cds {
|
|
|
25
31
|
|
|
26
32
|
}
|
|
27
33
|
|
|
28
|
-
|
|
29
34
|
type ConnectOptions = {
|
|
35
|
+
impl?: string,
|
|
36
|
+
service?: string,
|
|
30
37
|
kind?:string,
|
|
31
38
|
model?:string,
|
|
32
|
-
credentials
|
|
39
|
+
credentials?: object
|
|
33
40
|
}
|
package/apis/core.d.ts
CHANGED
package/apis/csn.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// in several places within the API.
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
export interface Constructable<T> {
|
|
6
|
+
export interface Constructable<T = any> {
|
|
7
7
|
new(...args: any[]): T
|
|
8
8
|
}
|
|
9
9
|
|
|
@@ -16,4 +16,17 @@ export interface ArrayConstructable<T = any> {
|
|
|
16
16
|
|
|
17
17
|
// concrete singular type.
|
|
18
18
|
// `SingularType<typeof Books>` == `Book`.
|
|
19
|
-
export type SingularType<T extends ArrayConstructable<T>> = InstanceType<T>[number]
|
|
19
|
+
export type SingularType<T extends ArrayConstructable<T>> = InstanceType<T>[number]
|
|
20
|
+
|
|
21
|
+
// Convenient way of unwrapping the inner type from array-typed values, as well as the value type itself
|
|
22
|
+
// `class MyArray<T> extends Array<T>``
|
|
23
|
+
// The latter is used heavily in the CDS typer, but its behaviour depends based on how the types are imported:
|
|
24
|
+
// If they are imported on a value based (`require('path/to/type')`) they will be considered `ArrayConstructable`.
|
|
25
|
+
// But if they are being used on type level (JSDOC: `/* @type {import('path/to/type')} */`) they are considered an `Array` .
|
|
26
|
+
// This type introduces an indirection that streamlines their behaviour for both cases.
|
|
27
|
+
// For any scalar type `Unwrap` behaves idempotent.
|
|
28
|
+
export type Unwrap<T> = T extends ArrayConstructable
|
|
29
|
+
? SingularType<T>
|
|
30
|
+
: T extends Array<infer U>
|
|
31
|
+
? U
|
|
32
|
+
: T
|
package/apis/log.d.ts
CHANGED
|
@@ -55,6 +55,16 @@ declare type LogFactory = {
|
|
|
55
55
|
* The formatter shall return an array of arguments, which are passed to the logger (for example, `console.log()`)
|
|
56
56
|
*/
|
|
57
57
|
format: Formatter
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Set a custom logger.
|
|
61
|
+
* ```
|
|
62
|
+
* cds.log.Logger = ...
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
Logger: Logger
|
|
66
|
+
|
|
67
|
+
winstonLogger (LoggerOptions?: {level?: string, levels?: any, format?: any, transports?: any, exitOnError?: boolean | Function, silent?: boolean})
|
|
58
68
|
}
|
|
59
69
|
|
|
60
70
|
declare class Logger {
|
package/apis/serve.d.ts
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import { Service, ServiceImpl } from "./services"
|
|
2
2
|
import { LinkedDefinition } from "./reflect"
|
|
3
3
|
import { csn } from "./csn"
|
|
4
|
-
import * as http from "http"
|
|
5
|
-
|
|
6
|
-
// stub to avoid hard dependencies for typescript projects
|
|
7
|
-
declare namespace express {
|
|
8
|
-
interface Application {}
|
|
9
|
-
}
|
|
4
|
+
import * as http from "http"
|
|
10
5
|
|
|
11
6
|
// export const Service : _Service
|
|
12
7
|
|
|
@@ -14,7 +9,7 @@ interface _fluent {
|
|
|
14
9
|
from (model : string | csn) : this
|
|
15
10
|
to (protocol: string) : this
|
|
16
11
|
at (path: string) : this
|
|
17
|
-
in (app:
|
|
12
|
+
in <T = any> (app: T) : this
|
|
18
13
|
with (impl: ServiceImpl | string) : this
|
|
19
14
|
// (req,res) : void
|
|
20
15
|
}
|
|
@@ -45,8 +40,8 @@ declare class cds_serve {
|
|
|
45
40
|
* express application has been constructed but no middlewares or routes
|
|
46
41
|
* added yet.
|
|
47
42
|
*/
|
|
48
|
-
on
|
|
49
|
-
once (event : 'bootstrap', listener : (app :
|
|
43
|
+
on <T = any> (event : 'bootstrap', listener : (app : T) => void) : this
|
|
44
|
+
once <T = any>(event : 'bootstrap', listener : (app : T) => void) : this
|
|
50
45
|
|
|
51
46
|
/**
|
|
52
47
|
* Emitted for each service served by cds.serve().
|
package/apis/services.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { SELECT, INSERT, UPDATE, DELETE, Query, ConstructedQuery, UPSERT } from './ql'
|
|
2
2
|
import { Projection, Proxy, Awaitable } from './ql'
|
|
3
|
-
import { ArrayConstructable } from './internal/inference'
|
|
3
|
+
import { ArrayConstructable, Unwrap, SingularType, Constructable } from './internal/inference'
|
|
4
4
|
import { LinkedModel, Definition, Definitions } from './reflect'
|
|
5
5
|
import { csn, type } from './csn'
|
|
6
|
+
import { User } from './core'
|
|
7
|
+
import { ref } from './cqn'
|
|
6
8
|
// import { Service } from './cds'
|
|
7
9
|
|
|
8
10
|
export class QueryAPI {
|
|
@@ -83,6 +85,11 @@ export class QueryAPI {
|
|
|
83
85
|
*/
|
|
84
86
|
tx(context?: object): Transaction
|
|
85
87
|
transaction(context?: object): Transaction
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* @see [docs](https://pages.github.tools.sap/cap/docs/node.js/cds-context-tx?q=spawn#cds-spawn)
|
|
91
|
+
*/
|
|
92
|
+
spawn(options: Options, fn: (tx: Transaction) => {}): SpawnEventEmitter
|
|
86
93
|
}
|
|
87
94
|
|
|
88
95
|
/**
|
|
@@ -186,7 +193,7 @@ export class Service extends QueryAPI {
|
|
|
186
193
|
* Constructs and sends a DELETE request.
|
|
187
194
|
*/
|
|
188
195
|
delete: {
|
|
189
|
-
(entityOrPath: Target, data?: object): DELETE<T>
|
|
196
|
+
<T = any>(entityOrPath: Target, data?: object): DELETE<T>
|
|
190
197
|
<T extends ArrayConstructable<any>>(entity: T, key?: any): DELETE<T>
|
|
191
198
|
<T>(entity: Definition | string, key?: any): DELETE<T>
|
|
192
199
|
}
|
|
@@ -196,14 +203,21 @@ export class Service extends QueryAPI {
|
|
|
196
203
|
|
|
197
204
|
// Provider API
|
|
198
205
|
prepend(fn: ServiceImpl): Promise<this>
|
|
206
|
+
on<T extends Constructable>(eve: Events, entity: T, handler: CRUDEventHandler.On<InstanceType<T>, InstanceType<T> | void | Error>): this
|
|
207
|
+
on<P,R>(boundAction: (args: P) => R, service: string, handler: ActionEventHandler<P, void | Error | R>): this
|
|
208
|
+
on<P,R>(action: (args: P) => R, handler: ActionEventHandler<P, void | Error | R>): this
|
|
199
209
|
on(eve: Events, entity: Target, handler: OnEventHandler): this
|
|
200
210
|
on(eve: Events, handler: OnEventHandler): this
|
|
211
|
+
|
|
212
|
+
|
|
201
213
|
// onSucceeded (eve: Events, entity: Target, handler: EventHandler): this
|
|
202
214
|
// onSucceeded (eve: Events, handler: EventHandler): this
|
|
203
215
|
// onFailed (eve: Events, entity: Target, handler: EventHandler): this
|
|
204
216
|
// onFailed (eve: Events, handler: EventHandler): this
|
|
217
|
+
before<T extends Constructable>(eve: Events, entity: T, handler: CRUDEventHandler.Before<InstanceType<T>, InstanceType<T> | void | Error>): this
|
|
205
218
|
before(eve: Events, entity: Target, handler: EventHandler): this
|
|
206
219
|
before(eve: Events, handler: EventHandler): this
|
|
220
|
+
after<T extends Constructable>(eve: Events, entity: T, handler: CRUDEventHandler.After<InstanceType<T>, InstanceType<T> | void | Error>): this
|
|
207
221
|
after(eve: Events, entity: Target, handler: ResultsHandler): this
|
|
208
222
|
after(eve: Events, handler: ResultsHandler): this
|
|
209
223
|
reject(eves: Events, ...entity: Target[]): this
|
|
@@ -263,6 +277,35 @@ export interface OnEventHandler {
|
|
|
263
277
|
(req: Request, next: Function): Promise<any> | any | void
|
|
264
278
|
}
|
|
265
279
|
|
|
280
|
+
// `Partial` wraps any type and allows all properties to be undefined
|
|
281
|
+
// in addition to their actual type.
|
|
282
|
+
// This is important in the context of CRUD events, where
|
|
283
|
+
// entities could be lacking any properties, like a non-existing ID
|
|
284
|
+
// or when DB fields are corrupted, etc.
|
|
285
|
+
type Partial<T> = { [Key in keyof T]: undefined | T[Key] }
|
|
286
|
+
|
|
287
|
+
// Naming the first parameter in a handler `each` has special voodoo
|
|
288
|
+
// semantic which makes it impossible for us to infer the exact behaviour on a type level.
|
|
289
|
+
// So we always have to expect scalars as well as arrays in some callbacks.
|
|
290
|
+
type OneOrMany<T> = T | T[];
|
|
291
|
+
|
|
292
|
+
type TypedRequest<T> = Omit<Request, 'data'> & { data: T }
|
|
293
|
+
|
|
294
|
+
// https://cap.cloud.sap/docs/node.js/services#event-handlers
|
|
295
|
+
export namespace CRUDEventHandler {
|
|
296
|
+
type Before<P,R> = (req: TypedRequest<P>) => Promise<R> | R
|
|
297
|
+
type On<P,R> = (req: TypedRequest<P>, next: (...args: any) => Promise<R> | R) => Promise<R> | R
|
|
298
|
+
type After<P,R> = (data: undefined | P, req: TypedRequest<P>) => Promise<R> | R
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Handlers for actions try to infer the passed .data property
|
|
302
|
+
// as strictly as possible and therefore have to remove
|
|
303
|
+
// { data: any } (inherited EventMessage} with a more restricted
|
|
304
|
+
// type, based on the parameters of the action.
|
|
305
|
+
export interface ActionEventHandler<P,R> {
|
|
306
|
+
(req: Omit<Request, 'data'> & { data: P }, next: Function): Promise<R> | R
|
|
307
|
+
}
|
|
308
|
+
|
|
266
309
|
// Note: the behaviour of ResultsHandler changes based on the name of the parameter.
|
|
267
310
|
// If the parameter in the hook is called "each", it is called once for each row in the result,
|
|
268
311
|
// otherwise it gets called exactly one time with the entire result.
|
|
@@ -296,6 +339,29 @@ interface EventMessage extends EventContext {
|
|
|
296
339
|
headers: {}
|
|
297
340
|
}
|
|
298
341
|
|
|
342
|
+
interface SpawnEvents {
|
|
343
|
+
'succeeded': (res: any) => void
|
|
344
|
+
'failed': (error: any) => void
|
|
345
|
+
'done': () => void
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
class SpawnEventEmitter {
|
|
349
|
+
on<U extends keyof SpawnEvents>(
|
|
350
|
+
event: U, listener: SpawnEvents[U]
|
|
351
|
+
): this;
|
|
352
|
+
|
|
353
|
+
emit<U extends keyof SpawnEvents>(
|
|
354
|
+
event: U, ...args: Parameters<SpawnEvents[U]>
|
|
355
|
+
): boolean;
|
|
356
|
+
timer: any
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
interface Options {
|
|
360
|
+
[key: string]: any
|
|
361
|
+
every?: number
|
|
362
|
+
after?: number
|
|
363
|
+
}
|
|
364
|
+
|
|
299
365
|
/**
|
|
300
366
|
* @see [capire docs](https://cap.cloud.sap/docs/node.js/requests)
|
|
301
367
|
*/
|
|
@@ -311,26 +377,27 @@ interface Request extends EventMessage {
|
|
|
311
377
|
*/
|
|
312
378
|
entity: string
|
|
313
379
|
query: Query
|
|
380
|
+
subject: ref
|
|
314
381
|
|
|
315
382
|
reply(results: any): void
|
|
316
383
|
|
|
317
|
-
notify(code: number,
|
|
318
|
-
info(code: number,
|
|
319
|
-
warn(code: number,
|
|
320
|
-
error(code: number,
|
|
321
|
-
reject(code: number,
|
|
322
|
-
|
|
323
|
-
notify(
|
|
324
|
-
info(
|
|
325
|
-
warn(
|
|
326
|
-
error(
|
|
327
|
-
reject(
|
|
328
|
-
|
|
329
|
-
notify(
|
|
330
|
-
info(
|
|
331
|
-
warn(
|
|
332
|
-
error(
|
|
333
|
-
reject(
|
|
384
|
+
notify(code: number, message: string, target?: string, args?: {}): Error
|
|
385
|
+
info(code: number, message: string, target?: string, args?: {}): Error
|
|
386
|
+
warn(code: number, message: string, target?: string, args?: {}): Error
|
|
387
|
+
error(code: number, message: string, target?: string, args?: {}): Error
|
|
388
|
+
reject(code: number, message: string, target?: string, args?: {}): Error
|
|
389
|
+
|
|
390
|
+
notify(message: string, target?: string, args?: {}): Error
|
|
391
|
+
info(message: string, target?: string, args?: {}): Error
|
|
392
|
+
warn(message: string, target?: string, args?: {}): Error
|
|
393
|
+
error(message: string, target?: string, args?: {}): Error
|
|
394
|
+
reject(message: string, target?: string, args?: {}): Error
|
|
395
|
+
|
|
396
|
+
notify(message: { code?: number | string; message: string; target?: string; args?: {} }): Error
|
|
397
|
+
info(message: { code?: number | string; message: string; target?: string; args?: {} }): Error
|
|
398
|
+
warn(message: { code?: number | string; message: string; target?: string; args?: {} }): Error
|
|
399
|
+
error(message: { code?: number | string; message: string; target?: string; args?: {}, status?: number }): Error
|
|
400
|
+
reject(message: { code?: number | string; message: string; target?: string; args?: {}, status?: number }): Error
|
|
334
401
|
}
|
|
335
402
|
|
|
336
403
|
type Events = Event | Event[]
|
|
@@ -3,7 +3,7 @@ const path = require('path')
|
|
|
3
3
|
const cds = require('./cds'), { log } = cds.exec
|
|
4
4
|
const { sortMessagesSeverityAware, deduplicateMessages, CompilationError } = require('@sap/cds-compiler')
|
|
5
5
|
const { relativePaths, BuildError, BuildMessage, resolveRequiredSapModels } = require('./util')
|
|
6
|
-
const { OUTPUT_MODE_DEFAULT, SEVERITIES, LOG_LEVELS, LOG_MODULE_NAMES
|
|
6
|
+
const { OUTPUT_MODE_DEFAULT, SEVERITIES, LOG_LEVELS, LOG_MODULE_NAMES } = require('./constants')
|
|
7
7
|
const BuildTaskProviderFactory = require('./buildTaskProviderFactory')
|
|
8
8
|
const BuildTaskHandlerInternal = require('./provider/buildTaskHandlerInternal')
|
|
9
9
|
|
|
@@ -42,13 +42,10 @@ class BuildTaskEngine {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
// validate required @sap namespace models - log only
|
|
45
|
-
const
|
|
45
|
+
const unresolved = BuildTaskEngine._resolveRequiredSapServices(tasks)
|
|
46
46
|
if (unresolved.length > 0) {
|
|
47
47
|
messages.push(new BuildMessage(`Required CDS service models [${unresolved.join(', ')}] cannot be resolved. Make sure to install the missing npm modules.`))
|
|
48
48
|
}
|
|
49
|
-
if (missing.length > 0) {
|
|
50
|
-
messages.push(new BuildMessage(`Required CDS service models [${missing.join(', ')}] are missing in custom build tasks. Make sure to add the missing models.`))
|
|
51
|
-
}
|
|
52
49
|
|
|
53
50
|
// create build task handlers
|
|
54
51
|
const handlers = []
|
|
@@ -184,7 +181,7 @@ class BuildTaskEngine {
|
|
|
184
181
|
return Promise.resolve({
|
|
185
182
|
task: handler.task,
|
|
186
183
|
result: handlerResult,
|
|
187
|
-
messages: BuildTaskEngine.
|
|
184
|
+
messages: BuildTaskEngine._sortMessagesUnique(buildOptions, handler.messages)
|
|
188
185
|
})
|
|
189
186
|
})
|
|
190
187
|
}))
|
|
@@ -206,28 +203,21 @@ class BuildTaskEngine {
|
|
|
206
203
|
}, [])
|
|
207
204
|
|
|
208
205
|
if (errors.length > 0) {
|
|
209
|
-
const
|
|
210
|
-
if (
|
|
211
|
-
throw
|
|
206
|
+
const error = errors.find(e => e.constructor.name !== COMPILATION_ERROR)
|
|
207
|
+
if (error) {
|
|
208
|
+
// throw original error, including BuildErrors
|
|
209
|
+
// for BuildErrors we do not merge other build messages that might exist in order to keep the original error intact
|
|
210
|
+
throw error
|
|
212
211
|
}
|
|
212
|
+
|
|
213
|
+
// propagate existing CompilationErrors
|
|
214
|
+
// merge all existing compilation messages into a single CompilationError
|
|
215
|
+
// compiler warning and info messages are returned as handler messages
|
|
213
216
|
const compileErrors = errors.filter(e => e.constructor.name === COMPILATION_ERROR)
|
|
214
|
-
let buildErrors = []
|
|
215
|
-
// NOTE: The order is important for now as for compatibility reasons the origin CompilationError
|
|
216
|
-
// is thrown in processTasks method.
|
|
217
|
-
// 1. compiler warnings are returned as handler messages
|
|
218
217
|
const compileMessages = handlerMessages.filter(message => message.constructor.name === COMPILE_MESSAGE)
|
|
219
|
-
if (compileErrors.length
|
|
220
|
-
|
|
221
|
-
buildErrors.push(compileError)
|
|
218
|
+
if (compileErrors.length) {
|
|
219
|
+
throw new CompilationError(BuildTaskEngine._sortMessagesUnique(buildOptions, BuildTaskEngine._getErrorMessages(compileErrors), compileMessages))
|
|
222
220
|
}
|
|
223
|
-
|
|
224
|
-
// 2. add other build errors
|
|
225
|
-
buildErrors = buildErrors.concat(errors.filter(e => e.name === BuildError.name))
|
|
226
|
-
|
|
227
|
-
// 3. add messages from build tasks
|
|
228
|
-
buildErrors = buildErrors.concat(handlerMessages.filter(message => message.name === BuildMessage.name))
|
|
229
|
-
|
|
230
|
-
throw new BuildError(`CDS build failed for [${buildOptions.root}]`, buildErrors)
|
|
231
221
|
}
|
|
232
222
|
return resolvedResults
|
|
233
223
|
}
|
|
@@ -312,23 +302,7 @@ class BuildTaskEngine {
|
|
|
312
302
|
return acc
|
|
313
303
|
}, new Set())
|
|
314
304
|
|
|
315
|
-
|
|
316
|
-
const model = cds.env.requires[srvName]?.model;
|
|
317
|
-
if (model) {
|
|
318
|
-
if (Array.isArray(model)) {
|
|
319
|
-
model.forEach(m => acc.add(m))
|
|
320
|
-
} else {
|
|
321
|
-
acc.add(model)
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
return acc
|
|
325
|
-
}, new Set())]
|
|
326
|
-
|
|
327
|
-
const unresolved = resolveRequiredSapModels([...taskModelPaths])
|
|
328
|
-
// are the required service models contained in the task's options.model
|
|
329
|
-
const missing = srvModelPaths.filter(m => m.startsWith('@sap/') && !CDS_MODEL_EXCLUDE_LIST.includes(m) && !taskModelPaths.has(m) && !unresolved.find(u => u === m))
|
|
330
|
-
|
|
331
|
-
return { unresolved, missing }
|
|
305
|
+
return resolveRequiredSapModels([...taskModelPaths])
|
|
332
306
|
}
|
|
333
307
|
|
|
334
308
|
/**
|
|
@@ -363,7 +337,7 @@ class BuildTaskEngine {
|
|
|
363
337
|
* @param {object} buildOptions
|
|
364
338
|
* @param {...Error} messages
|
|
365
339
|
*/
|
|
366
|
-
static
|
|
340
|
+
static _sortMessagesUnique(buildOptions, ...messages) {
|
|
367
341
|
const logLevelIdx = LOG_LEVELS.indexOf(this._getLogLevel(buildOptions))
|
|
368
342
|
// flatten
|
|
369
343
|
messages = messages.reduce((acc, m) => acc.concat(m), [])
|
package/bin/build/constants.js
CHANGED
|
@@ -20,7 +20,7 @@ exports.BUILD_TASKS = [this.BUILD_TASK_JAVA, this.BUILD_TASK_JAVA_CF, this.BUILD
|
|
|
20
20
|
exports.ODATA_VERSION_V2 = "v2"
|
|
21
21
|
exports.ODATA_VERSION_V4 = "v4"
|
|
22
22
|
|
|
23
|
-
exports.
|
|
23
|
+
exports.BUILD_NODEJS_EDMX_GENERATION = "build.nodejs.edmxgeneration" // WebIDE Fullstack
|
|
24
24
|
exports.EDMX_GENERATION = "edmxGeneration"
|
|
25
25
|
|
|
26
26
|
exports.SKIP_MANIFEST_GENERATION = "skipManifestGeneration"
|
|
@@ -40,13 +40,15 @@ exports.CONTENT_NODE_MODULES = "contentNodeModules" // copy node_modules
|
|
|
40
40
|
exports.CONTENT_ENV = "contentEnv" // copy .env file if existing into deployment folder
|
|
41
41
|
exports.CONTENT_DEFAULT_ENV_JSON = "contentDefaultEnvJson" // copy default-env.json file if existing into deployment folder
|
|
42
42
|
exports.CSV_FILE_DETECTION = "csvFileDetection" // detect CSV files based on CDS model location
|
|
43
|
+
exports.EXTENSION_POINT_VALIDATION = "extensionPointValidation" // validate extension point restrictions defined by the extended SaaS app
|
|
44
|
+
exports.DEFAULT_BUILT_IN_MODELS = "defaultBuiltInModels" // add @sap/cds* built-in models to build tasks
|
|
43
45
|
|
|
44
46
|
exports.FOLDER_GEN = "gen"
|
|
45
47
|
exports.FILE_EXT_CDS = ".cds"
|
|
46
48
|
exports.MTX_SIDECAR_FOLDER = "mtx/sidecar" // default name of the mtx sidecar folder
|
|
47
49
|
exports.DEFAULT_CSN_FILE_NAME = "csn.json"
|
|
48
50
|
// REVISIT: the models are not required if a custom server.js file is used for MTX bootstrap
|
|
49
|
-
exports.
|
|
51
|
+
exports.NODEJS_MODEL_EXCLUDE_LIST = ['@sap/cds/srv/mtx', '@sap/cds-mtxs/srv/bootstrap']
|
|
50
52
|
|
|
51
53
|
exports.CDS_CONFIG_PATH_SEP = "/"
|
|
52
54
|
exports.SKIP_ASSERT_COMPILER_V2 = "skip-assert-compiler-v2"
|