@sap/cds 7.3.1 → 7.4.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 +69 -3
- package/_i18n/i18n_es_MX.properties +110 -0
- package/apis/cds.d.ts +13 -12
- package/apis/core.d.ts +27 -108
- package/apis/cqn.d.ts +15 -18
- package/apis/csn.d.ts +95 -60
- package/apis/env.d.ts +25 -0
- package/apis/events.d.ts +125 -0
- package/apis/{reflect.d.ts → linked.d.ts} +29 -38
- package/apis/models.d.ts +60 -45
- package/apis/ql.d.ts +19 -5
- package/apis/{serve.d.ts → server.d.ts} +59 -33
- package/apis/services.d.ts +76 -147
- package/apis/test.d.ts +1 -1
- package/bin/serve.js +3 -0
- package/lib/compile/cds-compile.js +2 -2
- package/lib/compile/etc/csv.js +2 -1
- package/lib/compile/to/edm.js +8 -3
- package/lib/compile/to/gql.js +4 -0
- package/lib/dbs/cds-deploy.js +52 -4
- package/lib/env/cds-requires.js +27 -15
- package/lib/env/defaults.js +1 -0
- package/lib/env/schemas/index.js +10 -0
- package/lib/index.js +7 -4
- package/lib/linked/models.js +8 -5
- package/lib/ql/CREATE.js +2 -0
- package/lib/ql/DELETE.js +1 -0
- package/lib/ql/DROP.js +2 -0
- package/lib/ql/INSERT.js +2 -22
- package/lib/ql/Query.js +59 -22
- package/lib/ql/SELECT.js +5 -0
- package/lib/ql/STREAM.js +2 -0
- package/lib/ql/UPDATE.js +2 -0
- package/lib/ql/UPSERT.js +3 -1
- package/lib/ql/cds-ql.js +21 -5
- package/lib/ql/infer.js +129 -0
- package/lib/req/cds-context.js +8 -5
- package/lib/srv/cds-connect.js +3 -1
- package/lib/utils/axios.js +4 -2
- package/lib/utils/data.js +3 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +12 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +27 -9
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/batch/BatchProcessor.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/TrustedResourceJsonSerializer.js +8 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +11 -8
- package/libx/_runtime/common/code-ext/worker.js +5 -16
- package/libx/_runtime/common/generic/auth/capabilities.js +11 -2
- package/libx/_runtime/common/i18n/messages.properties +1 -0
- package/libx/_runtime/common/utils/postProcessing.js +1 -1
- package/libx/_runtime/common/utils/resolveView.js +28 -9
- package/libx/{common → _runtime/common}/utils/ucsn.js +19 -11
- package/libx/_runtime/db/expand/expandCQNToJoin.js +6 -6
- package/libx/_runtime/db/expand/rawToExpanded.js +4 -4
- package/libx/_runtime/db/sql-builder/InsertBuilder.js +6 -1
- package/libx/_runtime/db/sql-builder/UpdateBuilder.js +6 -1
- package/libx/_runtime/db/sql-builder/dollar.js +7 -7
- package/libx/_runtime/fiori/generic/activate.js +2 -2
- package/libx/_runtime/fiori/generic/edit.js +25 -45
- package/libx/_runtime/fiori/generic/read.js +3 -5
- package/libx/_runtime/fiori/lean-draft.js +171 -84
- package/libx/_runtime/fiori/utils/delete.js +7 -1
- package/libx/_runtime/fiori/utils/handler.js +4 -6
- package/libx/_runtime/fiori/utils/lockInfo.js +27 -0
- package/libx/_runtime/fiori/utils/where.js +20 -1
- package/libx/_runtime/messaging/AMQPWebhookMessaging.js +3 -2
- package/libx/_runtime/messaging/Outbox.js +12 -47
- package/libx/_runtime/messaging/common-utils/AMQPClient.js +1 -3
- package/libx/_runtime/messaging/common-utils/authorizedRequest.js +3 -0
- package/libx/_runtime/messaging/common-utils/connections.js +1 -1
- package/libx/_runtime/messaging/enterprise-messaging.js +12 -13
- package/libx/_runtime/messaging/file-based.js +7 -5
- package/libx/_runtime/messaging/redis-messaging.js +10 -11
- package/libx/_runtime/messaging/service.js +12 -26
- package/libx/_runtime/remote/Service.js +52 -36
- package/libx/_runtime/remote/utils/client.js +24 -125
- package/libx/odata/afterburner.js +16 -6
- package/libx/odata/grammar.peggy +26 -7
- package/libx/odata/metadata.js +18 -1
- package/libx/odata/parser.js +1 -1
- package/libx/odata/service-document.js +0 -1
- package/libx/odata/utils.js +19 -3
- package/libx/{_runtime/messaging/outbox/utils.js → outbox/index.js} +94 -24
- package/libx/rest/middleware/parse.js +1 -1
- package/package.json +2 -2
- package/apis/connect.d.ts +0 -39
- package/bin/utils/modules.js +0 -7
- package/bin/utils/term.js +0 -56
- package/lib/env/schema.js +0 -9
- package/lib/linked/queries.js +0 -41
- package/lib/srv/protocols/odata-v2-proxy.js +0 -3699
- package/libx/common/asserts.js +0 -0
- package/libx/common/crud.js +0 -0
- package/libx/common/etag.js +0 -0
- package/libx/common/localized.js +0 -0
- package/libx/common/managed.js +0 -0
- package/libx/common/paging.js +0 -0
- package/libx/common/readme.md +0 -4
- package/libx/common/sorting.js +0 -0
- package/libx/common/temporal.js +0 -0
- package/libx/connect/auth.js +0 -0
- package/libx/connect/perf.js +0 -0
- package/libx/connect/readme.md +0 -3
- package/libx/fiori/draft/readme.md +0 -1
- package/libx/fiori/readme.md +0 -1
- package/libx/hana/readme.md +0 -1
- package/libx/msg/readme.md +0 -3
- package/libx/readme.md +0 -1
- package/libx/sqlite/readme.md +0 -1
- /package/libx/_runtime/{messaging/common-utils → common/utils}/waitingTime.js +0 -0
- /package/libx/{_runtime/messaging/outbox → outbox}/OutboxRunner.js +0 -0
package/apis/services.d.ts
CHANGED
|
@@ -1,23 +1,21 @@
|
|
|
1
|
-
import { SELECT, INSERT, UPDATE, DELETE,
|
|
1
|
+
import { SELECT, INSERT, UPDATE, DELETE, Query, ConstructedQuery, UPSERT } from './ql'
|
|
2
2
|
import { Awaitable } from './ql'
|
|
3
3
|
import { ArrayConstructable, Constructable } from './internal/inference'
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
8
|
-
import { ref } from './cqn'
|
|
9
|
-
// import { Service } from './cds'
|
|
4
|
+
import { LinkedCSN, LinkedDefinition, Definitions, LinkedEntity } from './linked'
|
|
5
|
+
import { CSN } from './csn'
|
|
6
|
+
import { EventContext } from './events'
|
|
7
|
+
import { Request } from './events'
|
|
10
8
|
|
|
11
9
|
export class QueryAPI {
|
|
12
10
|
|
|
13
|
-
entities :
|
|
11
|
+
entities : LinkedCSN['entities']
|
|
14
12
|
|
|
15
13
|
/**
|
|
16
14
|
* @see [docs](https://cap.cloud.sap/docs/node.js/core-services#crud-style-api)
|
|
17
15
|
*/
|
|
18
16
|
read: {
|
|
19
17
|
<T extends ArrayConstructable<any>>(entity: T, key?: any): Awaitable<SELECT<T>, InstanceType<T>>
|
|
20
|
-
<T>(entity:
|
|
18
|
+
<T>(entity: LinkedDefinition | string, key?: any): SELECT<T>
|
|
21
19
|
}
|
|
22
20
|
|
|
23
21
|
/**
|
|
@@ -25,7 +23,7 @@ export class QueryAPI {
|
|
|
25
23
|
*/
|
|
26
24
|
create: {
|
|
27
25
|
<T extends ArrayConstructable<any>>(entity: T, key?: any): INSERT<T>
|
|
28
|
-
<T>(entity:
|
|
26
|
+
<T>(entity: LinkedDefinition | string, key?: any): INSERT<T>
|
|
29
27
|
}
|
|
30
28
|
|
|
31
29
|
/**
|
|
@@ -49,7 +47,7 @@ export class QueryAPI {
|
|
|
49
47
|
*/
|
|
50
48
|
update: {
|
|
51
49
|
<T extends ArrayConstructable<any>>(entity: T, key?: any): UPDATE<T>
|
|
52
|
-
<T>(entity:
|
|
50
|
+
<T>(entity: LinkedDefinition | string, key?: any): UPDATE<T>
|
|
53
51
|
}
|
|
54
52
|
|
|
55
53
|
/**
|
|
@@ -64,7 +62,7 @@ export class QueryAPI {
|
|
|
64
62
|
/**
|
|
65
63
|
* @see [docs](https://cap.cloud.sap/docs/node.js/core-services#crud-style-api)
|
|
66
64
|
*/
|
|
67
|
-
delete<T>(entity:
|
|
65
|
+
delete<T>(entity: LinkedDefinition | string, key?: any): DELETE<T>
|
|
68
66
|
|
|
69
67
|
/**
|
|
70
68
|
* @see [docs](https://cap.cloud.sap/docs/node.js/core-services#srv-foreach-entity)
|
|
@@ -76,7 +74,7 @@ export class QueryAPI {
|
|
|
76
74
|
*/
|
|
77
75
|
stream: {
|
|
78
76
|
(column: string): {
|
|
79
|
-
from(entity:
|
|
77
|
+
from(entity: LinkedDefinition | string): {
|
|
80
78
|
where(filter: any): ReadableStream
|
|
81
79
|
}
|
|
82
80
|
}
|
|
@@ -93,7 +91,7 @@ export class QueryAPI {
|
|
|
93
91
|
(context?: object): Transaction
|
|
94
92
|
(context: object, fn: (tx: Transaction) => {}): Promise<unknown>
|
|
95
93
|
}
|
|
96
|
-
|
|
94
|
+
|
|
97
95
|
transaction: {
|
|
98
96
|
(fn: (tx: Transaction) => {}): Promise<unknown>
|
|
99
97
|
(context?: object): Transaction
|
|
@@ -103,20 +101,18 @@ export class QueryAPI {
|
|
|
103
101
|
/**
|
|
104
102
|
* @see [docs](https://cap.cloud.sap/docs/node.js/cds-tx#cds-spawn)
|
|
105
103
|
*/
|
|
106
|
-
spawn(options:
|
|
104
|
+
spawn(options: {
|
|
105
|
+
[key: string]: any
|
|
106
|
+
every?: number
|
|
107
|
+
after?: number
|
|
108
|
+
}, fn: (tx: Transaction) => {}): SpawnEventEmitter
|
|
107
109
|
|
|
108
110
|
/**
|
|
109
111
|
* @see [docs](https://cap.cloud.sap/docs/node.js/cds-tx#event-contexts
|
|
110
112
|
*/
|
|
111
|
-
context
|
|
113
|
+
context?: EventContext
|
|
112
114
|
}
|
|
113
115
|
|
|
114
|
-
type ContextProperties = {
|
|
115
|
-
id?: string
|
|
116
|
-
http?: {req: express.Request, res: express.Response}
|
|
117
|
-
tenant? : string,
|
|
118
|
-
user? : User | string
|
|
119
|
-
}
|
|
120
116
|
|
|
121
117
|
/**
|
|
122
118
|
* Class cds.Service
|
|
@@ -124,9 +120,9 @@ type ContextProperties = {
|
|
|
124
120
|
*/
|
|
125
121
|
export class Service extends QueryAPI {
|
|
126
122
|
constructor(
|
|
127
|
-
name
|
|
128
|
-
model
|
|
129
|
-
options
|
|
123
|
+
name?: string,
|
|
124
|
+
model?: CSN,
|
|
125
|
+
options?: {
|
|
130
126
|
kind: string
|
|
131
127
|
impl: string | ServiceImpl
|
|
132
128
|
}
|
|
@@ -141,7 +137,7 @@ export class Service extends QueryAPI {
|
|
|
141
137
|
* The model from which the service's definition was loaded
|
|
142
138
|
* @see [capire docs](https://cap.cloud.sap/docs/node.js/core-services)
|
|
143
139
|
*/
|
|
144
|
-
model:
|
|
140
|
+
model: LinkedCSN
|
|
145
141
|
|
|
146
142
|
/**
|
|
147
143
|
* Provides access to the entities exposed by a service
|
|
@@ -179,8 +175,8 @@ export class Service extends QueryAPI {
|
|
|
179
175
|
* @see [capire docs](https://cap.cloud.sap/docs/core-services#srv-emit-event)
|
|
180
176
|
*/
|
|
181
177
|
emit: {
|
|
182
|
-
<T = any>(details: { event:
|
|
183
|
-
<T = any>(event:
|
|
178
|
+
<T = any>(details: { event: types.event; data?: object; headers?: object }): Promise<T>
|
|
179
|
+
<T = any>(event: types.event, data?: object, headers?: object): Promise<T>
|
|
184
180
|
}
|
|
185
181
|
|
|
186
182
|
/**
|
|
@@ -188,93 +184,84 @@ export class Service extends QueryAPI {
|
|
|
188
184
|
* @see [capire docs](https://cap.cloud.sap/docs/node.js/core-services#srv-send-request)
|
|
189
185
|
*/
|
|
190
186
|
send: {
|
|
191
|
-
<T = any>(event:
|
|
192
|
-
<T = any>(event:
|
|
193
|
-
<T = any>(details: { event:
|
|
187
|
+
<T = any>(event: types.event, path: string, data?: object, headers?: object): Promise<T>
|
|
188
|
+
<T = any>(event: types.event, data?: object, headers?: object): Promise<T>
|
|
189
|
+
<T = any>(details: { event: types.event; data?: object; headers?: object }): Promise<T>
|
|
194
190
|
<T = any>(details: { query: ConstructedQuery; data?: object; headers?: object }): Promise<T>
|
|
195
|
-
<T = any>(details: { method:
|
|
196
|
-
<T = any>(details: { event:
|
|
191
|
+
<T = any>(details: { method: types.eventName; path: string; data?: object; headers?: object }): Promise<T>
|
|
192
|
+
<T = any>(details: { event: types.eventName; entity: LinkedDefinition | string; data?: object; params?: object }): Promise<T>
|
|
197
193
|
}
|
|
198
194
|
|
|
199
195
|
/**
|
|
200
196
|
* Constructs and sends a GET request.
|
|
201
197
|
* @see [capire docs](https://cap.cloud.sap/docs/node.js/core-services#rest-style-api)
|
|
202
198
|
*/
|
|
203
|
-
get<T = any>(entityOrPath:
|
|
199
|
+
get<T = any>(entityOrPath: types.target, data?: object): Promise<T>
|
|
204
200
|
/**
|
|
205
201
|
* Constructs and sends a POST request.
|
|
206
202
|
* @see [capire docs](https://cap.cloud.sap/docs/node.js/core-services#rest-style-api)
|
|
207
203
|
*/
|
|
208
|
-
post<T = any>(entityOrPath:
|
|
204
|
+
post<T = any>(entityOrPath: types.target, data?: object): Promise<T>
|
|
209
205
|
/**
|
|
210
206
|
* Constructs and sends a PUT request.
|
|
211
207
|
* @see [capire docs](https://cap.cloud.sap/docs/node.js/core-services#rest-style-api)
|
|
212
208
|
*/
|
|
213
|
-
put<T = any>(entityOrPath:
|
|
209
|
+
put<T = any>(entityOrPath: types.target, data?: object): Promise<T>
|
|
214
210
|
/**
|
|
215
211
|
* Constructs and sends a PATCH request.
|
|
216
212
|
* @see [capire docs](https://cap.cloud.sap/docs/node.js/core-services#rest-style-api)
|
|
217
213
|
*/
|
|
218
|
-
patch<T = any>(entityOrPath:
|
|
214
|
+
patch<T = any>(entityOrPath: types.target, data?: object): Promise<T>
|
|
219
215
|
/**
|
|
220
216
|
* Constructs and sends a DELETE request.
|
|
221
217
|
*/
|
|
222
218
|
delete: {
|
|
223
|
-
<T = any>(entityOrPath:
|
|
219
|
+
<T = any>(entityOrPath: types.target, data?: object): DELETE<T>
|
|
224
220
|
<T extends ArrayConstructable<any>>(entity: T, key?: any): DELETE<T>
|
|
225
|
-
<T>(entity:
|
|
221
|
+
<T>(entity: LinkedDefinition | string, key?: any): DELETE<T>
|
|
226
222
|
}
|
|
227
223
|
|
|
228
224
|
// The central method to dispatch events
|
|
229
|
-
dispatch(msg:
|
|
225
|
+
dispatch(msg: types.event): Promise<any>
|
|
230
226
|
|
|
231
227
|
// Provider API
|
|
232
228
|
prepend(fn: ServiceImpl): Promise<this>
|
|
233
|
-
on<T extends Constructable>(eve:
|
|
229
|
+
on<T extends Constructable>(eve: types.event, entity: T, handler: CRUDEventHandler.On<InstanceType<T>, InstanceType<T> | void | Error>): this
|
|
234
230
|
on<F extends CdsFunction>(boundAction: F, service: string, handler: ActionEventHandler<F['__parameters'], void | Error | F['__returns']>): this
|
|
235
231
|
on<F extends CdsFunction>(unboundAction: F, handler: ActionEventHandler<F['__parameters'], void | Error | F['__returns']>): this
|
|
236
|
-
on(eve:
|
|
237
|
-
on(eve:
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
// onSucceeded (eve: Events, entity: Target, handler: EventHandler): this
|
|
241
|
-
// onSucceeded (eve: Events, handler: EventHandler): this
|
|
242
|
-
// onFailed (eve: Events, entity: Target, handler: EventHandler): this
|
|
243
|
-
// onFailed (eve: Events, handler: EventHandler): this
|
|
244
|
-
before<T extends Constructable>(eve:
|
|
245
|
-
before(eve:
|
|
246
|
-
before(eve:
|
|
247
|
-
after<T extends Constructable>(eve:
|
|
248
|
-
after(eve:
|
|
249
|
-
after(eve:
|
|
250
|
-
reject(eves:
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
export interface Transaction extends Service {
|
|
254
|
-
commit(): Promise<void>
|
|
255
|
-
rollback(): Promise<void>
|
|
232
|
+
on(eve: types.event, entity: types.target, handler: OnEventHandler): this
|
|
233
|
+
on(eve: types.event, handler: OnEventHandler): this
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
// onSucceeded (eve: types.Events, entity: types.Target, handler: types.EventHandler): this
|
|
237
|
+
// onSucceeded (eve: types.Events, handler: types.EventHandler): this
|
|
238
|
+
// onFailed (eve: types.Events, entity: types.Target, handler: types.EventHandler): this
|
|
239
|
+
// onFailed (eve: types.Events, handler: types.EventHandler): this
|
|
240
|
+
before<T extends Constructable>(eve: types.event, entity: T, handler: CRUDEventHandler.Before<InstanceType<T>, InstanceType<T> | void | Error>): this
|
|
241
|
+
before(eve: types.event, entity: types.target, handler: EventHandler): this
|
|
242
|
+
before(eve: types.event, handler: EventHandler): this
|
|
243
|
+
after<T extends Constructable>(eve: types.event, entity: T, handler: CRUDEventHandler.After<InstanceType<T>, InstanceType<T> | void | Error>): this
|
|
244
|
+
after(eve: types.event, entity: types.target, handler: ResultsHandler): this
|
|
245
|
+
after(eve: types.event, handler: ResultsHandler): this
|
|
246
|
+
reject(eves: types.event, ...entity: types.target[]): this
|
|
256
247
|
}
|
|
257
248
|
|
|
258
249
|
export class ApplicationService extends Service {}
|
|
259
250
|
export class MessagingService extends Service {}
|
|
260
251
|
export class RemoteService extends Service {}
|
|
261
252
|
export class DatabaseService extends Service {
|
|
262
|
-
deploy(model?:
|
|
253
|
+
deploy(model?: CSN | string): Promise<CSN>
|
|
263
254
|
begin(): Promise<void>
|
|
264
255
|
commit(): Promise<void>
|
|
265
256
|
rollback(): Promise<void>
|
|
266
257
|
}
|
|
267
258
|
|
|
268
|
-
export interface ResultSet extends Array<{}> {}
|
|
269
259
|
|
|
270
|
-
|
|
260
|
+
export default class cds {
|
|
271
261
|
/**
|
|
272
262
|
* @see [capire docs](https://cap.cloud.sap/docs/node.js/core-services)
|
|
273
263
|
*/
|
|
274
264
|
Service: typeof Service
|
|
275
|
-
Request: typeof Request
|
|
276
|
-
Event: typeof Event
|
|
277
|
-
EventContext: typeof EventContext
|
|
278
265
|
|
|
279
266
|
/**
|
|
280
267
|
* @see [capire docs](https://cap.cloud.sap/docs/node.js/app-services)
|
|
@@ -297,16 +284,24 @@ declare class cds {
|
|
|
297
284
|
DatabaseService: typeof DatabaseService
|
|
298
285
|
}
|
|
299
286
|
|
|
300
|
-
|
|
287
|
+
|
|
288
|
+
interface Transaction extends Service {
|
|
289
|
+
commit(): Promise<void>
|
|
290
|
+
rollback(): Promise<void>
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
interface ResultSet extends Array<{}> {}
|
|
294
|
+
|
|
295
|
+
interface ServiceImpl {
|
|
301
296
|
(this: Service, srv: Service): any
|
|
302
297
|
}
|
|
303
298
|
|
|
304
|
-
|
|
305
|
-
// (msg : EventMessage) : Promise<any> | any | void
|
|
299
|
+
interface EventHandler {
|
|
300
|
+
// (msg : types.EventMessage) : Promise<any> | any | void
|
|
306
301
|
(req: Request): Promise<any> | any | void
|
|
307
302
|
}
|
|
308
303
|
|
|
309
|
-
|
|
304
|
+
interface OnEventHandler {
|
|
310
305
|
(req: Request, next: Function): Promise<any> | any | void
|
|
311
306
|
}
|
|
312
307
|
|
|
@@ -335,7 +330,7 @@ type CdsFunction = {
|
|
|
335
330
|
type TypedRequest<T> = Omit<Request, 'data'> & { data: T }
|
|
336
331
|
|
|
337
332
|
// https://cap.cloud.sap/docs/node.js/core-services#srv-on-before-after
|
|
338
|
-
|
|
333
|
+
declare namespace CRUDEventHandler {
|
|
339
334
|
type Before<P,R> = (req: TypedRequest<P>) => Promise<R> | R
|
|
340
335
|
type On<P,R> = (req: TypedRequest<P>, next: (...args: any) => Promise<R> | R) => Promise<R> | R
|
|
341
336
|
type After<P,R> = (data: undefined | P, req: TypedRequest<P>) => Promise<R> | R
|
|
@@ -345,7 +340,7 @@ export namespace CRUDEventHandler {
|
|
|
345
340
|
// as strictly as possible and therefore have to remove
|
|
346
341
|
// { data: any } (inherited EventMessage} with a more restricted
|
|
347
342
|
// type, based on the parameters of the action.
|
|
348
|
-
|
|
343
|
+
interface ActionEventHandler<P,R> {
|
|
349
344
|
(req: Omit<Request, 'data'> & { data: P }, next: Function): Promise<R> | R
|
|
350
345
|
}
|
|
351
346
|
|
|
@@ -361,27 +356,6 @@ interface ResultsHandler {
|
|
|
361
356
|
(each: any, req: Request): void
|
|
362
357
|
}
|
|
363
358
|
|
|
364
|
-
/**
|
|
365
|
-
* Represents the invocation context of incoming request and event messages.
|
|
366
|
-
* @see [capire docs](https://cap.cloud.sap/docs/node.js/requests)
|
|
367
|
-
*/
|
|
368
|
-
export class EventContext {
|
|
369
|
-
timestamp: Date
|
|
370
|
-
locale: string
|
|
371
|
-
id: string
|
|
372
|
-
user: User
|
|
373
|
-
tenant: string
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
/**
|
|
377
|
-
* @see [capire docs](https://cap.cloud.sap/docs/node.js/requests)
|
|
378
|
-
*/
|
|
379
|
-
export class Event extends EventContext {
|
|
380
|
-
event: string
|
|
381
|
-
data: any
|
|
382
|
-
headers: {}
|
|
383
|
-
}
|
|
384
|
-
|
|
385
359
|
interface SpawnEvents {
|
|
386
360
|
'succeeded': (res: any) => void
|
|
387
361
|
'failed': (error: any) => void
|
|
@@ -399,57 +373,12 @@ declare class SpawnEventEmitter {
|
|
|
399
373
|
timer: any
|
|
400
374
|
}
|
|
401
375
|
|
|
402
|
-
|
|
403
|
-
[
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
*/
|
|
411
|
-
export class Request extends Event {
|
|
412
|
-
params: (string | {})[]
|
|
413
|
-
method: string
|
|
414
|
-
path: string
|
|
415
|
-
target: Definition
|
|
416
|
-
/**
|
|
417
|
-
* Shortcut to {@link target.name}
|
|
418
|
-
*
|
|
419
|
-
* @see https://cap.cloud.sap/docs/node.js/events#req-entity
|
|
420
|
-
*/
|
|
421
|
-
entity: string
|
|
422
|
-
query: CQNQuery
|
|
423
|
-
subject: ref
|
|
424
|
-
|
|
425
|
-
reply(results: any): void
|
|
426
|
-
|
|
427
|
-
notify(code: number, message: string, target?: string, args?: {}): Error
|
|
428
|
-
info(code: number, message: string, target?: string, args?: {}): Error
|
|
429
|
-
warn(code: number, message: string, target?: string, args?: {}): Error
|
|
430
|
-
error(code: number, message: string, target?: string, args?: {}): Error
|
|
431
|
-
reject(code: number, message: string, target?: string, args?: {}): Error
|
|
432
|
-
|
|
433
|
-
notify(message: string, target?: string, args?: {}): Error
|
|
434
|
-
info(message: string, target?: string, args?: {}): Error
|
|
435
|
-
warn(message: string, target?: string, args?: {}): Error
|
|
436
|
-
error(message: string, target?: string, args?: {}): Error
|
|
437
|
-
reject(message: string, target?: string, args?: {}): Error
|
|
438
|
-
|
|
439
|
-
notify(message: { code?: number | string; message: string; target?: string; args?: {} }): Error
|
|
440
|
-
info(message: { code?: number | string; message: string; target?: string; args?: {} }): Error
|
|
441
|
-
warn(message: { code?: number | string; message: string; target?: string; args?: {} }): Error
|
|
442
|
-
error(message: { code?: number | string; message: string; target?: string; args?: {}, status?: number }): Error
|
|
443
|
-
reject(message: { code?: number | string; message: string; target?: string; args?: {}, status?: number }): Error
|
|
376
|
+
declare namespace types {
|
|
377
|
+
type event = eventName | eventName[]
|
|
378
|
+
type eventName = (string & {})
|
|
379
|
+
| 'CREATE' | 'READ' | 'UPDATE' | 'DELETE'
|
|
380
|
+
| 'NEW' | 'EDIT' | 'PATCH' | 'SAVE'
|
|
381
|
+
| 'GET' | 'PUT' | 'POST' | 'PATCH' | 'DELETE'
|
|
382
|
+
| 'COMMIT' | 'ROLLBACK'
|
|
383
|
+
type target = string | LinkedDefinition | LinkedEntity | (string | LinkedDefinition | LinkedEntity)[] | ArrayConstructable<any>
|
|
444
384
|
}
|
|
445
|
-
|
|
446
|
-
export default cds
|
|
447
|
-
|
|
448
|
-
type EventArg = EventName | EventName[]
|
|
449
|
-
type EventName = (CRUD | TX | HTTP | DRAFT) | (CustomOp & {})
|
|
450
|
-
type CRUD = 'CREATE' | 'READ' | 'UPDATE' | 'DELETE'
|
|
451
|
-
type DRAFT = 'NEW' | 'EDIT' | 'PATCH' | 'SAVE'
|
|
452
|
-
type HTTP = 'GET' | 'PUT' | 'POST' | 'PATCH' | 'DELETE'
|
|
453
|
-
type TX = 'COMMIT' | 'ROLLBACK'
|
|
454
|
-
type CustomOp = string
|
|
455
|
-
type Target = string | Definition | ArrayConstructable<any>
|
package/apis/test.d.ts
CHANGED
package/bin/serve.js
CHANGED
|
@@ -191,6 +191,9 @@ async function serve (all=[], o={}) {
|
|
|
191
191
|
// bootstrap server from project-local server.js or from @sap/cds/server.js
|
|
192
192
|
const server = await cds_server(o)
|
|
193
193
|
|
|
194
|
+
// increase keep-alive timeout for CF (gorouter wants >90s)
|
|
195
|
+
if (process.env.CF_INSTANCE_GUID) server.keepAliveTimeout = 91 * 1000
|
|
196
|
+
|
|
194
197
|
// return a promise which resolves to the created http server when listening
|
|
195
198
|
return cds.server.listening = new Promise ((_resolve,_reject) => {
|
|
196
199
|
|
|
@@ -15,7 +15,6 @@ const compile = module.exports = Object.assign (cds_compile, {
|
|
|
15
15
|
to: new class {
|
|
16
16
|
get csn() { return super.csn = require('./to/csn') }
|
|
17
17
|
get cdl() { return super.cdl = require('./to/cdl') }
|
|
18
|
-
get gql() { return super.gql = require('./to/gql') }
|
|
19
18
|
get yml() { return super.yml = require('./to/yaml') }
|
|
20
19
|
get yaml() { return super.yaml = require('./to/yaml') }
|
|
21
20
|
get json() { return super.json = require('./to/json') }
|
|
@@ -26,7 +25,8 @@ const compile = module.exports = Object.assign (cds_compile, {
|
|
|
26
25
|
get hdbtable() { return super.hdbtable = compile.to.sql.hdbtable }
|
|
27
26
|
get hdbtabledata() { return super.hdbtabledata = require('./to/hdbtabledata') }
|
|
28
27
|
get serviceinfo() { return super.serviceinfo = require('./to/srvinfo') } //> REVISIT: move to CLI
|
|
29
|
-
get
|
|
28
|
+
get gql() { return super.gql = require('./to/gql') } //> REVISIT: moved to @cap-js/graphql, remove with cds^8
|
|
29
|
+
get graphql() { return super.graphql = require('./to/gql') } //> REVISIT: moved to @cap-js/graphql, remove with cds^8
|
|
30
30
|
},
|
|
31
31
|
|
|
32
32
|
})
|
package/lib/compile/etc/csv.js
CHANGED
|
@@ -12,7 +12,8 @@ function read (res) {
|
|
|
12
12
|
function parse (csv) {
|
|
13
13
|
if (csv[0] === BOM) csv = csv.slice(1)
|
|
14
14
|
let sep
|
|
15
|
-
|
|
15
|
+
// this also means that \r\n within quotes is NOT retained but normalized to \n. We accept this for now.
|
|
16
|
+
const lines = csv.split(/\r?\n/)
|
|
16
17
|
const rows = [], headers = []
|
|
17
18
|
|
|
18
19
|
let val, values=[]
|
package/lib/compile/to/edm.js
CHANGED
|
@@ -3,9 +3,14 @@ const cds = require ('../../index')
|
|
|
3
3
|
|
|
4
4
|
if (cds.env.features.precompile_edms !== false) {
|
|
5
5
|
const _precompiled = new WeakMap
|
|
6
|
-
cdsc.to.edm = Object.assign
|
|
7
|
-
if (
|
|
8
|
-
|
|
6
|
+
cdsc.to.edm = Object.assign((csn, o) => {
|
|
7
|
+
if (o.to === 'openapi') return cdsc.to.edm.all(csn, o)[o.service]
|
|
8
|
+
if (!_precompiled.has(csn)) {
|
|
9
|
+
// only for services that are served via odata
|
|
10
|
+
const serviceNames = o.serviceNames || Object.values(csn.definitions).filter(d => d.kind === 'service' && d.endpoints?.some(e => e.kind.match(/odata/i))).map(d => d.name)
|
|
11
|
+
_precompiled.set(csn, cdsc.to.edm.all(csn, Object.assign({ serviceNames }, o)))
|
|
12
|
+
}
|
|
13
|
+
return _precompiled.get(csn)[o.service]
|
|
9
14
|
}, { all: cdsc.to.edm.all })
|
|
10
15
|
}
|
|
11
16
|
|
package/lib/compile/to/gql.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
const cds = require ('../..')
|
|
2
|
+
const LOG = cds.log()
|
|
2
3
|
// eslint-disable-next-line cds/no-missing-dependencies -- needs to be added by app dev
|
|
3
4
|
const { SchemaGenerator } = require('@cap-js/graphql/lib/schema')
|
|
4
5
|
|
|
6
|
+
// REVISIT: remove module with cds^8
|
|
5
7
|
function cds_compile_to_gql (csn) {
|
|
8
|
+
LOG._warn && LOG.warn('WARNING: cds.compile.to.gql and .to.graphql will require @cap-js/graphql >= 0.9.0 with an upcoming release. Please update your dependency.')
|
|
9
|
+
|
|
6
10
|
const m = cds.linked(csn)
|
|
7
11
|
const services = Object.fromEntries(m.services.map(s => [s.name, new cds.ApplicationService(s.name, m)]))
|
|
8
12
|
return new SchemaGenerator().generate(services).printSchema()
|
package/lib/dbs/cds-deploy.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
const cds = require('../index'), { local } = cds.utils
|
|
3
|
+
const crypto = require('crypto')
|
|
3
4
|
const COLORS = !!process.stdout.isTTY && !!process.stderr.isTTY && !process.env.NO_COLOR
|
|
4
5
|
const GREY = COLORS ? '\x1b[2m' : ''
|
|
5
6
|
const RESET = COLORS ? '\x1b[0m' : ''
|
|
@@ -211,7 +212,7 @@ exports.init = async function cds_deploy_init (db, csn=db.model, o, srces, log=(
|
|
|
211
212
|
const m = tx.model = cds.compile.for.nodejs(csn) //> use correct model while deploying
|
|
212
213
|
const data = await exports.data (m,srces)
|
|
213
214
|
const query = _queries4 (db,m)
|
|
214
|
-
const INSERT_from = INSERT_from4 (db,o)
|
|
215
|
+
const INSERT_from = INSERT_from4 (db,m,o)
|
|
215
216
|
|
|
216
217
|
for await (let [ file, entity, src ] of data) {
|
|
217
218
|
log (file)
|
|
@@ -344,21 +345,67 @@ const _queries4 = (db,csn) => !db.cqn2sql ? q => q : q => {
|
|
|
344
345
|
}
|
|
345
346
|
|
|
346
347
|
|
|
347
|
-
const INSERT_from4 = (db,o) => {
|
|
348
|
+
const INSERT_from4 = (db,m,o) => {
|
|
348
349
|
const schevo = o?.schema_evolution === 'auto' || db.options.schema_evolution === 'auto'
|
|
349
350
|
const INSERT_into = (schevo ? UPSERT : INSERT).into
|
|
350
351
|
return (file) => ({
|
|
351
352
|
'.json': { into (entity, json) {
|
|
352
353
|
let records = JSON.parse(json)
|
|
353
|
-
if (records.length > 0)
|
|
354
|
+
if (records.length > 0) {
|
|
355
|
+
fill_ID_texts_json(records, m, entity)
|
|
356
|
+
return INSERT_into(entity).entries(records)
|
|
357
|
+
}
|
|
354
358
|
}},
|
|
355
359
|
'.csv': { into (entity, csv) {
|
|
356
360
|
let [cols, ...rows] = cds.parse.csv(csv)
|
|
357
|
-
if (rows.length > 0)
|
|
361
|
+
if (rows.length > 0) {
|
|
362
|
+
fill_ID_texts_csv(cols, rows, m, entity)
|
|
363
|
+
return INSERT_into(entity).columns(cols).rows(rows)
|
|
364
|
+
}
|
|
358
365
|
}},
|
|
359
366
|
}) [path.extname(file)]
|
|
360
367
|
}
|
|
361
368
|
|
|
369
|
+
const fill_ID_texts_json = (records, m, entity) => {
|
|
370
|
+
const baseKey = idTextsBaseKey(m, entity)
|
|
371
|
+
if (baseKey) {
|
|
372
|
+
records.forEach(record => {
|
|
373
|
+
if (!record.ID_texts) {
|
|
374
|
+
record.ID_texts = hashedUUID(record[baseKey], record.locale)
|
|
375
|
+
}
|
|
376
|
+
})
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const fill_ID_texts_csv = (cols, rows, m, entity) => {
|
|
381
|
+
const baseKey = idTextsBaseKey(m, entity)
|
|
382
|
+
if (baseKey && !cols.find(r => r.toLowerCase() === 'id_texts')) { // and no such column in csv?
|
|
383
|
+
DEBUG?.(`adding ID_texts for ${entity}`)
|
|
384
|
+
const indexBaseKey = cols.findIndex(c => c.toLowerCase() === baseKey.toLowerCase())
|
|
385
|
+
const indexLocale = cols.findIndex(c => c.toLowerCase() === 'locale')
|
|
386
|
+
rows.forEach(row => {
|
|
387
|
+
const idtexts = hashedUUID(row[indexBaseKey], row[indexLocale])
|
|
388
|
+
row.push(idtexts)
|
|
389
|
+
})
|
|
390
|
+
cols.push('ID_texts')
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
const idTextsBaseKey = (m, entity) => {
|
|
395
|
+
let base
|
|
396
|
+
if (m.definitions[entity]?.keys?.ID_texts // ID_text key?
|
|
397
|
+
&& /(.+)[._]texts$/.test(entity) && (base = m.definitions[RegExp.$1])) { // in a .text entity?
|
|
398
|
+
const baseKey = Object.keys(base.keys)[0] // base entity's key is usually, but not always 'ID'
|
|
399
|
+
return baseKey
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
const hashedUUID = (...values) => {
|
|
404
|
+
const sum = values.reduce((acc, curr) => acc + curr, '')
|
|
405
|
+
const h = crypto.createHash('md5').update(sum).digest('hex')
|
|
406
|
+
return h.slice(0, 8) + '-' + h.slice(8, 12) + '-' + h.slice(12, 16) + '-' + h.slice(16, 20) + '-' + h.slice(20)
|
|
407
|
+
}
|
|
408
|
+
|
|
362
409
|
const _skip = e => !e || e['@cds.persistence.skip'] === true
|
|
363
410
|
|
|
364
411
|
|
|
@@ -385,3 +432,4 @@ if (!module.parent) (async () => {
|
|
|
385
432
|
await db?.disconnect?.()
|
|
386
433
|
}
|
|
387
434
|
})().catch(console.error)
|
|
435
|
+
|
package/lib/env/cds-requires.js
CHANGED
|
@@ -160,6 +160,24 @@ const _databases = {
|
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
|
|
163
|
+
const _outbox = {
|
|
164
|
+
|
|
165
|
+
outbox: {
|
|
166
|
+
kind: "persistent-outbox",
|
|
167
|
+
parallel: true
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
"in-memory-outbox": {},
|
|
171
|
+
"persistent-outbox": {
|
|
172
|
+
model: "@sap/cds/srv/outbox",
|
|
173
|
+
maxAttempts: 20,
|
|
174
|
+
chunkSize: 100,
|
|
175
|
+
storeLastError: true
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
|
|
163
181
|
const _messaging = {
|
|
164
182
|
|
|
165
183
|
"local-messaging": {
|
|
@@ -167,9 +185,9 @@ const _messaging = {
|
|
|
167
185
|
local: true
|
|
168
186
|
},
|
|
169
187
|
"file-based-messaging": {
|
|
170
|
-
outbox: {},
|
|
171
188
|
impl: `${_runtime}/messaging/file-based.js`,
|
|
172
|
-
file:'~/.cds-msg-box'
|
|
189
|
+
file:'~/.cds-msg-box',
|
|
190
|
+
outbox: true
|
|
173
191
|
},
|
|
174
192
|
"default-messaging": {
|
|
175
193
|
"[development]": { kind: "local-messaging" },
|
|
@@ -186,19 +204,19 @@ const _messaging = {
|
|
|
186
204
|
kind: "enterprise-messaging-amqp",
|
|
187
205
|
},
|
|
188
206
|
"enterprise-messaging-http": {
|
|
189
|
-
outbox: {},
|
|
190
207
|
deployForProvider: true,
|
|
191
208
|
impl: `${_runtime}/messaging/enterprise-messaging.js`,
|
|
192
209
|
vcap: { label: "enterprise-messaging" },
|
|
210
|
+
outbox: true
|
|
193
211
|
},
|
|
194
212
|
"enterprise-messaging-amqp": {
|
|
195
|
-
outbox: {},
|
|
196
213
|
impl: `${_runtime}/messaging/enterprise-messaging-shared.js`,
|
|
197
214
|
vcap: { label: "enterprise-messaging" },
|
|
215
|
+
outbox: true
|
|
198
216
|
},
|
|
199
217
|
'message-queuing': {
|
|
200
|
-
|
|
201
|
-
|
|
218
|
+
impl: `${_runtime}/messaging/message-queuing.js`,
|
|
219
|
+
outbox: true
|
|
202
220
|
},
|
|
203
221
|
"composite-messaging": {
|
|
204
222
|
impl: `${_runtime}/messaging/composite.js`
|
|
@@ -212,15 +230,8 @@ const _messaging = {
|
|
|
212
230
|
"redis-messaging": {
|
|
213
231
|
impl: `${_runtime}/messaging/redis-messaging.js`,
|
|
214
232
|
vcap: { label: "redis-cache" },
|
|
215
|
-
outbox:
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
"persistent-outbox": {
|
|
219
|
-
model: "@sap/cds/srv/outbox",
|
|
220
|
-
maxAttempts: 20,
|
|
221
|
-
chunkSize: 100,
|
|
222
|
-
storeLastError: true
|
|
223
|
-
},
|
|
233
|
+
outbox: true
|
|
234
|
+
}
|
|
224
235
|
|
|
225
236
|
}
|
|
226
237
|
|
|
@@ -242,6 +253,7 @@ exports.kinds = {
|
|
|
242
253
|
..._authentication_strategies,
|
|
243
254
|
..._databases,
|
|
244
255
|
..._services,
|
|
256
|
+
..._outbox,
|
|
245
257
|
..._messaging,
|
|
246
258
|
..._platform_services,
|
|
247
259
|
}
|
package/lib/env/defaults.js
CHANGED
|
@@ -43,6 +43,7 @@ const defaults = module.exports = {
|
|
|
43
43
|
preview: !production,
|
|
44
44
|
routes: !production,
|
|
45
45
|
lean_draft: true,
|
|
46
|
+
wrap_multiple_errors: true, // switch default with cds 8
|
|
46
47
|
draft_compat: undefined,
|
|
47
48
|
'[better-sqlite]': { lean_draft: true },
|
|
48
49
|
'[lean-draft]': { lean_draft: true },
|