@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.
Files changed (136) hide show
  1. package/CHANGELOG.md +72 -2
  2. package/README.md +1 -1
  3. package/apis/connect.d.ts +11 -4
  4. package/apis/core.d.ts +1 -1
  5. package/apis/csn.d.ts +1 -0
  6. package/apis/internal/inference.d.ts +15 -2
  7. package/apis/log.d.ts +10 -0
  8. package/apis/serve.d.ts +4 -9
  9. package/apis/services.d.ts +86 -19
  10. package/bin/build/buildTaskEngine.js +16 -42
  11. package/bin/build/constants.js +4 -2
  12. package/bin/build/provider/buildTaskProviderInternal.js +117 -85
  13. package/bin/build/provider/hana/index.js +6 -1
  14. package/bin/build/provider/mtx-extension/index.js +74 -34
  15. package/bin/build/provider/mtx-sidecar/index.js +3 -3
  16. package/bin/build/provider/nodejs/index.js +2 -2
  17. package/bin/build/util.js +63 -14
  18. package/bin/cds-serve.js +6 -0
  19. package/bin/cds.js +22 -4
  20. package/bin/deploy/to-hana/cfUtil.js +15 -1
  21. package/bin/mtx/in-cds.js +2 -9
  22. package/bin/plugins.js +31 -0
  23. package/bin/serve.js +12 -12
  24. package/lib/compile/etc/_localized.js +1 -1
  25. package/lib/compile/for/lean_drafts.js +23 -6
  26. package/lib/compile/for/nodejs.js +4 -1
  27. package/lib/compile/load.js +4 -2
  28. package/lib/core/index.js +35 -15
  29. package/lib/dbs/cds-deploy.js +129 -133
  30. package/lib/env/cds-env.js +25 -17
  31. package/lib/env/cds-requires.js +10 -40
  32. package/lib/env/compat.js +12 -0
  33. package/lib/env/defaults.js +17 -9
  34. package/lib/env/plugins.js +29 -0
  35. package/lib/env/schemas/cds-rc.json +14 -0
  36. package/lib/index.js +3 -0
  37. package/lib/log/cds-log.js +7 -4
  38. package/lib/ql/CREATE.js +1 -1
  39. package/lib/ql/DELETE.js +1 -1
  40. package/lib/ql/DROP.js +3 -3
  41. package/lib/ql/INSERT.js +1 -1
  42. package/lib/ql/Query.js +14 -6
  43. package/lib/ql/SELECT.js +8 -2
  44. package/lib/ql/UPDATE.js +1 -1
  45. package/lib/ql/Whereable.js +1 -1
  46. package/lib/ql/cds-ql.js +1 -9
  47. package/lib/req/cds-context.js +1 -4
  48. package/lib/req/request.js +63 -2
  49. package/lib/req/response.js +3 -2
  50. package/lib/srv/bindings.js +69 -71
  51. package/lib/srv/cds-connect.js +4 -1
  52. package/lib/srv/cds-serve.js +4 -0
  53. package/lib/srv/middlewares/index.js +37 -6
  54. package/lib/srv/protocols/_legacy.js +1 -1
  55. package/lib/srv/protocols/index.js +1 -1
  56. package/lib/srv/srv-api.js +4 -6
  57. package/lib/srv/srv-dispatch.js +4 -3
  58. package/lib/srv/srv-handlers.js +1 -1
  59. package/lib/srv/srv-methods.js +8 -2
  60. package/lib/utils/cds-test.js +4 -1
  61. package/libx/_runtime/audit/Service.js +8 -9
  62. package/libx/_runtime/audit/generic/personal/index.js +1 -1
  63. package/libx/_runtime/audit/generic/personal/utils.js +1 -1
  64. package/libx/_runtime/audit/utils/v2.js +17 -20
  65. package/libx/_runtime/auth/strategies/mock.js +1 -1
  66. package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +2 -0
  67. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +1 -1
  68. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +1 -1
  69. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/delete.js +1 -1
  70. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +12 -5
  71. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +1 -2
  72. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/readToCQN.js +5 -5
  73. package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +1 -1
  74. package/libx/_runtime/cds-services/adapter/odata-v4/utils/metaInfo.js +4 -4
  75. package/libx/_runtime/cds-services/adapter/odata-v4/utils/oDataConfiguration.js +2 -2
  76. package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +1 -1
  77. package/libx/_runtime/cds-services/services/Service.js +28 -1
  78. package/libx/_runtime/cds-services/util/assert.js +41 -65
  79. package/libx/_runtime/common/code-ext/WorkerPool.js +90 -0
  80. package/libx/_runtime/common/code-ext/WorkerReq.js +0 -4
  81. package/libx/_runtime/common/code-ext/execute.js +28 -18
  82. package/libx/_runtime/common/code-ext/handlers.js +5 -4
  83. package/libx/_runtime/common/code-ext/worker.js +45 -3
  84. package/libx/_runtime/common/code-ext/workerQueryExecutor.js +8 -7
  85. package/libx/_runtime/common/composition/delete.js +1 -1
  86. package/libx/_runtime/common/composition/update.js +3 -5
  87. package/libx/_runtime/common/generic/auth/expand.js +1 -1
  88. package/libx/_runtime/common/generic/auth/readOnly.js +5 -4
  89. package/libx/_runtime/common/generic/auth/restrict.js +7 -2
  90. package/libx/_runtime/common/generic/auth/utils.js +5 -2
  91. package/libx/_runtime/common/generic/crud.js +12 -1
  92. package/libx/_runtime/common/generic/etag.js +11 -3
  93. package/libx/_runtime/common/generic/input.js +8 -6
  94. package/libx/_runtime/common/generic/paging.js +25 -8
  95. package/libx/_runtime/common/generic/put.js +1 -1
  96. package/libx/_runtime/common/generic/sorting.js +0 -1
  97. package/libx/_runtime/common/i18n/messages.properties +1 -0
  98. package/libx/_runtime/common/utils/cqn.js +5 -1
  99. package/libx/_runtime/common/utils/cqn2cqn4sql.js +3 -3
  100. package/libx/_runtime/common/utils/resolveView.js +14 -10
  101. package/libx/_runtime/common/utils/rewriteAsterisks.js +2 -3
  102. package/libx/_runtime/common/utils/templateProcessor.js +15 -17
  103. package/libx/_runtime/common/utils/templateProcessorPathSerializer.js +18 -6
  104. package/libx/_runtime/db/Service.js +1 -0
  105. package/libx/_runtime/db/data-conversion/post-processing.js +0 -18
  106. package/libx/_runtime/db/expand/expand-v2.js +2 -2
  107. package/libx/_runtime/db/expand/rawToExpanded.js +6 -6
  108. package/libx/_runtime/db/generic/integrity.js +1 -1
  109. package/libx/_runtime/db/utils/columns.js +5 -5
  110. package/libx/_runtime/fiori/generic/activate.js +3 -3
  111. package/libx/_runtime/fiori/generic/edit.js +1 -1
  112. package/libx/_runtime/fiori/generic/new.js +4 -0
  113. package/libx/_runtime/fiori/lean-draft.js +178 -68
  114. package/libx/_runtime/hana/execute.js +3 -1
  115. package/libx/_runtime/hana/pool.js +10 -2
  116. package/libx/_runtime/hana/search2cqn4sql.js +1 -1
  117. package/libx/_runtime/messaging/common-utils/AMQPClient.js +6 -1
  118. package/libx/_runtime/messaging/enterprise-messaging.js +1 -0
  119. package/libx/_runtime/remote/Service.js +16 -13
  120. package/libx/_runtime/remote/utils/client.js +6 -1
  121. package/libx/_runtime/sqlite/Service.js +5 -59
  122. package/libx/_runtime/sqlite/convertDraftAdminPathExpression.js +1 -0
  123. package/libx/_runtime/sqlite/customBuilder/CustomUpsertBuilder.js +2 -2
  124. package/libx/_runtime/sqlite/execute.js +3 -1
  125. package/libx/_runtime/types/api.js +12 -3
  126. package/libx/odata/afterburner.js +38 -2
  127. package/libx/odata/cqn2odata.js +3 -2
  128. package/libx/odata/grammar.pegjs +5 -3
  129. package/libx/odata/parser.js +1 -1
  130. package/libx/odata/utils.js +1 -1
  131. package/libx/rest/RestAdapter.js +1 -1
  132. package/libx/rest/RestRequest.js +1 -0
  133. package/package.json +5 -2
  134. package/libx/_runtime/common/code-ext/workerQuery.js +0 -45
  135. package/libx/_runtime/common/constants/limit.js +0 -12
  136. 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/api#cds-connect)
10
+ * @see [capire](https://cap.cloud.sap/docs/node.js/cds-connect#cds-connect-to)
11
11
  */
12
- to (datasource?: string, options?: ConnectOptions) : Promise<Service>
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: object,
39
+ credentials?: object
33
40
  }
package/apis/core.d.ts CHANGED
@@ -4,7 +4,7 @@ import { CSN as csn, Definition } from './csn'
4
4
 
5
5
  type UserInput = string | { id: string; attr: Record<string, string>; roles: Record<string, string> } | User
6
6
 
7
- declare class User {
7
+ export class User {
8
8
  constructor(obj?: UserInput)
9
9
  id: string
10
10
  /**
package/apis/csn.d.ts CHANGED
@@ -66,6 +66,7 @@ export interface entity extends struct {
66
66
  keys : {
67
67
  [name:string]: Definition
68
68
  }
69
+ drafts: entity
69
70
  }
70
71
 
71
72
  export interface Association extends type {
@@ -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: express.Application) : this
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 (event : 'bootstrap', listener : (app : express.Application) => void) : this
49
- once (event : 'bootstrap', listener : (app : express.Application) => void) : this
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().
@@ -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, msg: string, target?: string, args?: {}): Error
318
- info(code: number, msg: string, target?: string, args?: {}): Error
319
- warn(code: number, msg: string, target?: string, args?: {}): Error
320
- error(code: number, msg: string, target?: string, args?: {}): Error
321
- reject(code: number, msg: string, target?: string, args?: {}): Error
322
-
323
- notify(msg: string, target?: string, args?: {}): Error
324
- info(msg: string, target?: string, args?: {}): Error
325
- warn(msg: string, target?: string, args?: {}): Error
326
- error(msg: string, target?: string, args?: {}): Error
327
- reject(msg: string, target?: string, args?: {}): Error
328
-
329
- notify(msg: { code?: number | string; msg: string; target?: string; args?: {} }): Error
330
- info(msg: { code?: number | string; msg: string; target?: string; args?: {} }): Error
331
- warn(msg: { code?: number | string; msg: string; target?: string; args?: {} }): Error
332
- error(msg: { code?: number | string; msg: string; target?: string; args?: {} }): Error
333
- reject(msg: { code?: number | string; msg: string; target?: string; args?: {} }): Error
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, CDS_MODEL_EXCLUDE_LIST } = require('./constants')
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 { unresolved, missing } = BuildTaskEngine._resolveRequiredSapServices(tasks)
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._sortCompilationErrorsUnique(buildOptions, handler.messages)
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 internalError = errors.find(e => e.constructor.name !== COMPILATION_ERROR && e.name !== BuildError.name)
210
- if (internalError) {
211
- throw internalError
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 > 0) {
220
- const compileError = new CompilationError(BuildTaskEngine._sortCompilationErrorsUnique(buildOptions, BuildTaskEngine._getErrorMessages(compileErrors), compileMessages))
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
- const srvModelPaths = [...Object.keys(cds.env.requires || {}).reduce((acc, srvName) => {
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 _sortCompilationErrorsUnique(buildOptions, ...messages) {
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), [])
@@ -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.BUILD_NODEJS_EDMX_GENERAION = "build.nodejs.edmxgeneration" // WebIDE Fullstack
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.CDS_MODEL_EXCLUDE_LIST = ['@sap/cds/srv/mtx', '@sap/cds-mtxs/srv/bootstrap']
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"