@sap/cds 9.6.2 → 9.6.4
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 +13 -0
- package/lib/srv/bindings.js +8 -1
- package/libx/queue/index.js +8 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,19 @@
|
|
|
4
4
|
- The format is based on [Keep a Changelog](https://keepachangelog.com/).
|
|
5
5
|
- This project adheres to [Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## Version 9.6.4 - 2026-01-20
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- `queue`: Too eager removal of control data from deserialized task
|
|
12
|
+
- Stop overriding existing `cds.requires.[service].credentials` configurations using values from `.cds-services.json`
|
|
13
|
+
|
|
14
|
+
## Version 9.6.3 - 2026-01-14
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- `queue`: Exactly-once guarantee only with `legacyLocking: false`
|
|
19
|
+
|
|
7
20
|
## Version 9.6.2 - 2026-01-08
|
|
8
21
|
|
|
9
22
|
### Fixed
|
package/lib/srv/bindings.js
CHANGED
|
@@ -20,16 +20,21 @@ class Bindings {
|
|
|
20
20
|
bind (service) {
|
|
21
21
|
let required = cds.requires [service]
|
|
22
22
|
let binding = this.provides [required?.service || service]
|
|
23
|
-
|
|
23
|
+
|
|
24
|
+
if (binding?.endpoints && !required.credentials) {
|
|
25
|
+
// > Re-route requests to the mock service running locally
|
|
26
|
+
|
|
24
27
|
const server = this.servers [binding.server]
|
|
25
28
|
const kind = [ required?.kind, 'hcql', 'rest', 'odata' ].find (k => k in binding.endpoints)
|
|
26
29
|
const path = binding.endpoints [kind]
|
|
30
|
+
|
|
27
31
|
// in case of cds.requires.Foo = { ... }
|
|
28
32
|
if (typeof required === 'object') required.credentials = {
|
|
29
33
|
...required.credentials,
|
|
30
34
|
...binding.credentials,
|
|
31
35
|
url: server.url + path
|
|
32
36
|
}
|
|
37
|
+
|
|
33
38
|
// in case of cds.requires.Foo = true
|
|
34
39
|
else required = cds.requires[service] = cds.env.requires[service] = {
|
|
35
40
|
...cds.requires.kinds [binding.kind],
|
|
@@ -38,11 +43,13 @@ class Bindings {
|
|
|
38
43
|
url: server.url + path
|
|
39
44
|
}
|
|
40
45
|
}
|
|
46
|
+
|
|
41
47
|
required.kind = kind
|
|
42
48
|
// REVISIT: temporary fix to inherit kind as well for mocked odata services
|
|
43
49
|
// otherwise mocking with two services does not work for kind:odata-v2
|
|
44
50
|
if (kind === 'odata-v2' || kind === 'odata-v4') required.kind = 'odata'
|
|
45
51
|
}
|
|
52
|
+
|
|
46
53
|
return required
|
|
47
54
|
}
|
|
48
55
|
|
package/libx/queue/index.js
CHANGED
|
@@ -191,7 +191,8 @@ const _processTasks = (target, tenant, _opts = {}) => {
|
|
|
191
191
|
const _msg = _safeJSONParse(_task.msg)
|
|
192
192
|
|
|
193
193
|
const context = _msg.context || {}
|
|
194
|
-
|
|
194
|
+
// REVISIT: controlled context propagation
|
|
195
|
+
// delete _msg.context
|
|
195
196
|
|
|
196
197
|
const userId = _msg[INTERNAL_USER]
|
|
197
198
|
delete _msg[INTERNAL_USER]
|
|
@@ -244,7 +245,8 @@ const _processTasks = (target, tenant, _opts = {}) => {
|
|
|
244
245
|
const _run = opts.legacyLocking && cds.db?.kind === 'sqlite' ? cds._with : service.tx.bind(service)
|
|
245
246
|
const result = await _run({ ...task.context, tenant }, async () => {
|
|
246
247
|
const result = opts.handle ? await opts.handle.call(service, task.msg) : await service.handle(task.msg)
|
|
247
|
-
|
|
248
|
+
// we can only delete in the current tx if legacyLocking (i.e., long-lasting db locks) is false
|
|
249
|
+
if (!opts.legacyLocking) await DELETE.from(tasksEntity).where({ ID: task.ID })
|
|
248
250
|
return result
|
|
249
251
|
})
|
|
250
252
|
task.results = result
|
|
@@ -295,13 +297,15 @@ const _processTasks = (target, tenant, _opts = {}) => {
|
|
|
295
297
|
}
|
|
296
298
|
|
|
297
299
|
const queries = []
|
|
298
|
-
|
|
300
|
+
const _toBeDeleted = opts.legacyLocking ? toBeDeleted.concat(succeeded) : toBeDeleted
|
|
301
|
+
if (_toBeDeleted.length) {
|
|
299
302
|
queries.push(
|
|
300
303
|
DELETE.from(tasksEntity).where(
|
|
301
304
|
'ID in',
|
|
302
|
-
|
|
305
|
+
_toBeDeleted.map(msg => msg.ID)
|
|
303
306
|
)
|
|
304
307
|
)
|
|
308
|
+
}
|
|
305
309
|
|
|
306
310
|
// There can be tasks which are not updated / deleted, their status must be set back to `null`
|
|
307
311
|
const updateTasks = selectedTasks.filter(
|