@sap/cds 5.6.2 → 5.6.3

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 CHANGED
@@ -4,6 +4,16 @@
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 5.6.3 - 2021-11-15
8
+
9
+ ### Fixed
10
+
11
+ - `cds run` does not fail if `cds.requires.multitenancy` is explicitly set to `false`
12
+ - Calculation of `DraftIsCreatedByMe` or `DraftIsProcessedByMe` when expanding or navigating to `DraftAdministrativeData`
13
+ - Nested `any` in `$filter` query option
14
+ - Crash on draft activate after draft edit for not existing composition of one, if no explicit DB service is defined
15
+ - Typescript definition of `srv.delete` no longer leads to a duplication error
16
+
7
17
  ## Version 5.6.2 - 2021-11-08
8
18
 
9
19
  ### Fixed
@@ -165,6 +165,10 @@ export class Service extends QueryAPI {
165
165
  * @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-send)
166
166
  */
167
167
  delete (entityOrPath: Target, data?: object) : Promise<this>
168
+ /**
169
+ * @see [docs](https://cap.cloud.sap/docs/node.js/services#srv-run)
170
+ */
171
+ delete <T>(entity : Definition | string, key?: any) : DELETE<T>
168
172
 
169
173
  // The central method to dispatch events
170
174
  dispatch (msg: EventMessage): Promise<any>
package/lib/env/index.js CHANGED
@@ -242,7 +242,11 @@ _loadFromPath (_path, _basePath) {
242
242
 
243
243
  _link_required_services () {
244
244
  const { requires } = this, protos = requires && requires._prototypes || {}
245
- for (let each in requires) requires[each] = _merged (each)
245
+ for (let each in requires) {
246
+ requires[each] = _merged (each)
247
+ // if we got an invalid value, remove it (would anyways cause trouble down the road)
248
+ if (!requires[each]) delete requires[each]
249
+ }
246
250
  function _merged (key) {
247
251
  const entry = requires[key] || protos[key]
248
252
  if (!entry || entry._is_merged || entry.kind === key || !(entry.kind in requires) && !(entry.kind in protos)) return entry
@@ -59,6 +59,8 @@ class ExpressionToCQN {
59
59
  }
60
60
 
61
61
  _lambda(pathSegments) {
62
+ // we don't care about the variable name
63
+ if (pathSegments[0].getKind() === 'EXPRESSION.VARIABLE') pathSegments = pathSegments.slice(1)
62
64
  const nav =
63
65
  pathSegments.length > 2 ? pathSegments.slice(0, pathSegments.length - 2).map(this._segmentFromMember) : []
64
66
  const navName = this._segmentFromMember(pathSegments[pathSegments.length - 2])
@@ -208,7 +208,10 @@ function _addSubDeepUpdateCQNRecursion({ definitions, compositionTree, entity, d
208
208
  const selectEntry = selectDataByKey.get(_serializedKey(entity, entry))
209
209
 
210
210
  if (selectEntry && element.name in selectEntry) {
211
- if (selectEntry[element.name] === null && Object.keys(entry[element.name]).length === 0) {
211
+ if (
212
+ selectEntry[element.name] === null &&
213
+ (entry[element.name] === null || Object.keys(entry[element.name]).length === 0)
214
+ ) {
212
215
  continue
213
216
  }
214
217
  _addToData(selectSubData, entity, element, selectEntry)
@@ -257,12 +257,29 @@ const _getOuterMostColumns = (columnsFromRequest, additionalDraftColumns) => {
257
257
  return columns
258
258
  }
259
259
 
260
+ // adds base columns 'InProcessByUser' and 'CreatedByUser' to columns param if needed
261
+ // those are required for calculating 'DraftIsProcessedByMe' and 'DraftIsCreatedByMe'
262
+ const _ensureDraftAdminColumnsForCalculation = columns => {
263
+ columns.forEach((c, i) => {
264
+ if (c.ref && c.ref[0] === 'DraftIsCreatedByMe' && !columns.find(e => e.ref && e.ref[0] === 'CreatedByUser')) {
265
+ columns.push({ ref: ['CreatedByUser'] })
266
+ } else if (
267
+ c.ref &&
268
+ c.ref[0] === 'DraftIsProcessedByMe' &&
269
+ !columns.find(e => e.ref && e.ref[0] === 'InProcessByUser')
270
+ ) {
271
+ columns.push({ ref: ['InProcessByUser'] })
272
+ }
273
+ })
274
+ }
275
+
260
276
  const _draftAdminTable = req => {
261
277
  const { table } = _getTableName(req)
262
278
 
263
279
  let cqn = SELECT.from(table)
264
280
  if (req.query.SELECT.columns) {
265
281
  cqn = cqn.columns(...req.query.SELECT.columns)
282
+ _ensureDraftAdminColumnsForCalculation(cqn.SELECT.columns)
266
283
  }
267
284
 
268
285
  return {
@@ -1119,6 +1136,14 @@ const _getLocalizedEntity = (model, target, user) => {
1119
1136
  return localizedEntity || model.definitions[`${prefix}.${target.name}`]
1120
1137
  }
1121
1138
 
1139
+ const _adaptDraftAdminExpand = cqn => {
1140
+ const draftAdminExpand =
1141
+ cqn.SELECT.columns && cqn.SELECT.columns.find(c => c.expand && c.ref[0] === 'DraftAdministrativeData')
1142
+ if (draftAdminExpand) {
1143
+ _ensureDraftAdminColumnsForCalculation(draftAdminExpand.expand)
1144
+ }
1145
+ }
1146
+
1122
1147
  /**
1123
1148
  * Generic Handler for READ requests in the context of draft.
1124
1149
  *
@@ -1154,6 +1179,9 @@ const _handler = async function (req) {
1154
1179
  return
1155
1180
  }
1156
1181
 
1182
+ // ensure base columns for calculation are selected in draft admin expand
1183
+ _adaptDraftAdminExpand(cqnScenario.cqn)
1184
+
1157
1185
  if (cqnScenario.scenario === SCENARIO.ALL_ACTIVE && cqnScenario.cqn.SELECT.where) {
1158
1186
  cqnScenario.cqn.SELECT.where = removeIsActiveEntityRecursively(cqnScenario.cqn.SELECT.where)
1159
1187
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sap/cds",
3
- "version": "5.6.2",
3
+ "version": "5.6.3",
4
4
  "description": "SAP Cloud Application Programming Model - CDS for Node.js",
5
5
  "homepage": "https://cap.cloud.sap/",
6
6
  "keywords": [