@sap/cds 7.9.3 → 7.9.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 +10 -0
- package/libx/_runtime/common/composition/insert.js +3 -3
- package/libx/_runtime/db/query/read.js +18 -9
- package/libx/_runtime/fiori/lean-draft.js +1 -1
- package/libx/_runtime/messaging/event-broker.js +3 -4
- package/libx/odata/middleware/read.js +1 -1
- package/libx/odata/parse/cqn2odata.js +3 -3
- package/package.json +2 -2
- package/tasks/enterprise-messaging-deploy.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,16 @@
|
|
|
5
5
|
- This project adheres to [Semantic Versioning](http://semver.org/).
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
## Version 7.9.4 - 2024-07-18
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- View resolving for `cds.features.lean_draft`
|
|
13
|
+
- Error in `enterprise-messaging` deploy script
|
|
14
|
+
- Properly forward path expression infront of lamda functions for `odata-v2` remote services
|
|
15
|
+
- OData queries selecting the same column with `$count=true`
|
|
16
|
+
- Closed higher end of version range for dependency on `cds-types`
|
|
17
|
+
|
|
8
18
|
## Version 7.9.3 - 2024-06-27
|
|
9
19
|
|
|
10
20
|
### Fixed
|
|
@@ -4,7 +4,7 @@ const { getCompositionTree } = require('./tree')
|
|
|
4
4
|
const ctUtils = require('./utils')
|
|
5
5
|
|
|
6
6
|
const { ensureNoDraftsSuffix } = require('../utils/draft')
|
|
7
|
-
const {
|
|
7
|
+
const { deepCopy } = require('../utils/copy')
|
|
8
8
|
|
|
9
9
|
/*
|
|
10
10
|
* own utils
|
|
@@ -82,8 +82,8 @@ const hasDeepInsert = (model, cqn) => {
|
|
|
82
82
|
const getDeepInsertCQNs = (model, cqn) => {
|
|
83
83
|
const into = (cqn.INSERT.into.ref && cqn.INSERT.into.ref[0]) || cqn.INSERT.into.name || cqn.INSERT.into
|
|
84
84
|
const entityName = ensureNoDraftsSuffix(into)
|
|
85
|
-
const draft = entityName !== into
|
|
86
|
-
const dataEntries = cqn.INSERT.entries ?
|
|
85
|
+
const draft = entityName !== into || into.endsWith('.drafts') //lean draft
|
|
86
|
+
const dataEntries = cqn.INSERT.entries ? deepCopy(cqn.INSERT.entries) : []
|
|
87
87
|
const entity = model.definitions[entityName]
|
|
88
88
|
const compositionTree = getCompositionTree({
|
|
89
89
|
definitions: model.definitions,
|
|
@@ -60,17 +60,26 @@ const read = (executeSelectCQN, executeStreamCQN, convertStreams) => (model, dbc
|
|
|
60
60
|
|
|
61
61
|
if (query.SELECT.count) {
|
|
62
62
|
if (query.SELECT.limit) {
|
|
63
|
+
// IMPORTANT: do not change order!
|
|
64
|
+
// 1. create the count query synchronously, because it works on a copy
|
|
65
|
+
// 2. run the result query, duplicate names ( SELECT ID, ID ...) throw an error synchronously
|
|
66
|
+
// 3. run the count query
|
|
67
|
+
// reason is that executeSelectCQN modifies the query
|
|
63
68
|
const countQuery = _createCountQuery(query)
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
+
const resultPromise =
|
|
70
|
+
query.SELECT.limit?.rows?.val === 0
|
|
71
|
+
? Promise.resolve([])
|
|
72
|
+
: executeSelectCQN(model, dbc, query, user, locale, isoTs)
|
|
73
|
+
const countPromise = executeSelectCQN(model, dbc, countQuery, user, locale, isoTs)
|
|
69
74
|
|
|
70
|
-
|
|
71
|
-
return Promise.
|
|
72
|
-
|
|
73
|
-
|
|
75
|
+
// use allSettled here, so all executions are awaited before we rollback
|
|
76
|
+
return Promise.allSettled([countPromise, resultPromise]).then(results => {
|
|
77
|
+
const rejection = results.find(p => p.status === 'rejected')
|
|
78
|
+
if (rejection) throw rejection.reason
|
|
79
|
+
|
|
80
|
+
const [{ value: countResult }, { value: result }] = results
|
|
81
|
+
return _arrayWithCount(result, countValue(countResult))
|
|
82
|
+
})
|
|
74
83
|
}
|
|
75
84
|
|
|
76
85
|
return executeSelectCQN(model, dbc, query, user, locale, isoTs).then(result =>
|
|
@@ -771,7 +771,7 @@ const Read = {
|
|
|
771
771
|
else ownNewDrafts.push(draft)
|
|
772
772
|
}
|
|
773
773
|
|
|
774
|
-
const $count = ownDrafts.length + (isCount ? actives[0]?.$count : actives.$count ?? 0)
|
|
774
|
+
const $count = ownDrafts.length + (isCount ? actives[0]?.$count : (actives.$count ?? 0))
|
|
775
775
|
if (isCount) return { $count }
|
|
776
776
|
|
|
777
777
|
Read.merge(query._target, ownDrafts, [], row => {
|
|
@@ -195,10 +195,9 @@ class EventBroker extends cds.MessagingService {
|
|
|
195
195
|
data: req.body ? req.body : undefined,
|
|
196
196
|
headers: req.headers
|
|
197
197
|
}
|
|
198
|
-
|
|
199
|
-
if (tenant)
|
|
200
|
-
|
|
201
|
-
await tx.emit(msg)
|
|
198
|
+
const context = { user: cds.User.privileged }
|
|
199
|
+
if (tenant) context.tenant = tenant // TODO: In single tenant case, we don't need a tenant
|
|
200
|
+
await this.tx(context, tx => tx.emit(msg))
|
|
202
201
|
this.LOG.debug('Event processed successfully.')
|
|
203
202
|
return res.status(200).json({ message: 'OK' })
|
|
204
203
|
} catch (e) {
|
|
@@ -104,7 +104,7 @@ const _count = result => {
|
|
|
104
104
|
? result.reduce((acc, val) => {
|
|
105
105
|
return acc + (val?.$count ?? val?._counted_ ?? (Array.isArray(val) && _count(val))) || 0
|
|
106
106
|
}, 0)
|
|
107
|
-
: result.$count ?? result._counted_ ?? 0
|
|
107
|
+
: (result.$count ?? result._counted_ ?? 0)
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
// basically stolen from old read handler without understanding it ^^
|
|
@@ -177,13 +177,13 @@ function _xpr(expr, target, kind, isLambda) {
|
|
|
177
177
|
if (inExpr) res.push(`(${inExpr})`)
|
|
178
178
|
i += 1
|
|
179
179
|
} else if (_isLambda(cur, expr[i + 1])) {
|
|
180
|
-
const { where
|
|
181
|
-
const nav =
|
|
180
|
+
const { where } = expr[i + 1].ref.at(-1)
|
|
181
|
+
const nav = expr[i + 1].ref.map(ref => ref?.id ?? ref).join('/')
|
|
182
182
|
// odata-v2 does not support lambda expressions but successfactors allows filter like for to-one assocs
|
|
183
183
|
if (kind === 'odata-v2') {
|
|
184
184
|
cds.log('remote').info(`OData V2 does not support lambda expressions. Using path expression as best effort.`)
|
|
185
185
|
isLambda = false
|
|
186
|
-
res.push(`${
|
|
186
|
+
res.push(`${nav}%2F${_xpr(where, target, kind)}`)
|
|
187
187
|
} else if (!where) res.push(`${nav}/any()`)
|
|
188
188
|
else res.push(`${nav}/any(${LAMBDA_VARIABLE}:${_xpr(where, target, kind, true)})`)
|
|
189
189
|
i++
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sap/cds",
|
|
3
|
-
"version": "7.9.
|
|
3
|
+
"version": "7.9.4",
|
|
4
4
|
"description": "SAP Cloud Application Programming Model - CDS for Node.js",
|
|
5
5
|
"homepage": "https://cap.cloud.sap/",
|
|
6
6
|
"keywords": [
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"node": ">=16"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@cap-js/cds-types": "
|
|
36
|
+
"@cap-js/cds-types": "<=0.2.0",
|
|
37
37
|
"@sap/cds-compiler": "^4",
|
|
38
38
|
"@sap/cds-fiori": "^1",
|
|
39
39
|
"@sap/cds-foss": "^5.0.0"
|