@sap/cds 5.7.1 → 5.7.2

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.7.2 - 2021-12-09
8
+
9
+ ### Fixed
10
+
11
+ - Instance-based restriction for activation of draft enabled entities
12
+ - `.columns('*')` on projections of remote services using renamed properties
13
+ - GraphQL filters on nested fields are now applied correctly
14
+ - Performance degradation during processing of `where exists`
15
+ - Read drafts via navigation with complex filter expression
16
+
7
17
  ## Version 5.7.1 - 2021-12-06
8
18
 
9
19
  ### Fixed
@@ -8,7 +8,7 @@ const { SELECT } = cds.ql
8
8
  const { getRequiresAsArray } = require('../utils/auth')
9
9
  const { cqn2cqn4sql } = require('../utils/cqn2cqn4sql')
10
10
  const { isActiveEntityRequested, removeIsActiveEntityRecursively } = require('../../fiori/utils/where')
11
- const { ensureDraftsSuffix, ensureNoDraftsSuffix } = require('../../fiori/utils/handler')
11
+ const { ensureNoDraftsSuffix } = require('../../fiori/utils/handler')
12
12
  const { rewriteExpandAsterisk } = require('../../common/utils/rewriteAsterisks')
13
13
 
14
14
  const WRITE = ['CREATE', 'UPDATE', 'DELETE']
@@ -445,12 +445,11 @@ const _getUnrestrictedCount = async req => {
445
445
  const _getRestrictedCount = async (req, model, resolvedApplicables) => {
446
446
  const dbtx = cds.tx(req)
447
447
 
448
- let target =
448
+ const target =
449
449
  (req.query.UPDATE && req.query.UPDATE.entity) ||
450
450
  (req.query.DELETE && req.query.DELETE.from) ||
451
451
  (req.query.SELECT && req.query.SELECT.from)
452
- // REVISIT: req._ gets set in onDraftActivate to original req
453
- if (req._ && req._.event === 'draftActivate') target = ensureDraftsSuffix(target)
452
+
454
453
  const selectRestricted = SELECT.one(['count(*) as n']).from(target)
455
454
 
456
455
  const whereRestricted = (req.query.UPDATE && req.query.UPDATE.where) || (req.query.DELETE && req.query.DELETE.where)
@@ -445,35 +445,36 @@ const _ensureExpandedNestedWhereExists = ({ ref }, aliases) => {
445
445
  return { ref: [acc] }
446
446
  }
447
447
 
448
- const convertWhereExists = (cqn, model, options) => {
449
- function _recurse(where) {
450
- where.forEach((element, index) => {
451
- // ensure where exists are fully expanded
452
- if (where && where.some(ele => ele === 'exists')) {
453
- where.forEach((element, index) => {
454
- if (element === 'exists' && where[index + 1].ref) {
455
- const aliases = cqn.SELECT.from.as
456
- ? [cqn.SELECT.from.as]
457
- : cqn.SELECT.from.join
458
- ? cqn.SELECT.from.args.map(arg => arg.as)
459
- : []
460
- where[index + 1] = _ensureExpandedNestedWhereExists(where[index + 1], aliases)
461
- }
462
- })
463
- }
448
+ const _convertWhereExists = (where, cqn, model, options) => {
449
+ for (let i = 0; i < where.length; i++) {
450
+ const element = where[i]
451
+
452
+ // ensure where exists are fully expanded
453
+ if (
454
+ (element === 'exists' && where[i + 1].ref && where[i > 1 ? i - 1 : 0] !== 'not') ||
455
+ (element === 'not' && where[i + 1] === 'exists' && where[i + 2].ref)
456
+ ) {
457
+ const offset = element === 'not' ? 2 : 1
458
+ const aliases = cqn.SELECT.from.as
459
+ ? [cqn.SELECT.from.as]
460
+ : cqn.SELECT.from.join
461
+ ? cqn.SELECT.from.args.map(arg => arg.as)
462
+ : []
463
+ where[i + offset] = _ensureExpandedNestedWhereExists(where[i + offset], aliases)
464
+ }
464
465
 
465
- if (element.xpr) {
466
- _recurse(element.xpr) // recursing into nested {xpr}
467
- } else if (element === 'exists' && _isAny(where[index + 1])) {
468
- where[index + 1] = _getWhereExistsSubSelect(cqn, where, index + 1, model, options)
469
- } else if (element === 'not' && where[index + 1] === 'exists' && _isAll(where[index + 2])) {
470
- where[index + 2] = _getWhereExistsSubSelect(cqn, where, index + 2, model, options)
471
- }
472
- })
466
+ if (element.xpr) {
467
+ _convertWhereExists(element.xpr) // > recursing into nested {xpr}
468
+ } else if (element === 'exists' && _isAny(where[i + 1])) {
469
+ where[i + 1] = _getWhereExistsSubSelect(cqn, where, i + 1, model, options)
470
+ } else if (element === 'not' && where[i + 1] === 'exists' && _isAll(where[i + 2])) {
471
+ where[i + 2] = _getWhereExistsSubSelect(cqn, where, i + 2, model, options)
472
+ }
473
473
  }
474
+ }
474
475
 
475
- const where = cqn.SELECT.where
476
- if (where) _recurse(where)
476
+ const convertWhereExists = (cqn, model, options) => {
477
+ if (cqn.SELECT.where) _convertWhereExists(cqn.SELECT.where, cqn, model, options)
477
478
  }
478
479
 
479
480
  const _getRefIndex = (where, index) => {
@@ -338,7 +338,7 @@ const _newSelect = (query, transitions, service) => {
338
338
  if (!newSelect.columns && targetTransition.mapping.size) newSelect.columns = _initialColumns(targetTransition)
339
339
  if (newSelect.columns) {
340
340
  const isDB = service instanceof cds.DatabaseService
341
- rewriteAsterisks({ SELECT: newSelect }, service.model, isDB)
341
+ rewriteAsterisks({ SELECT: query.SELECT }, service.model, isDB)
342
342
  newSelect.columns = _newColumns(newSelect.columns, targetTransition, service, service.kind !== 'app-service')
343
343
  }
344
344
  if (newSelect.having) newSelect.having = _newColumns(newSelect.having, targetTransition)
@@ -1084,6 +1084,10 @@ const _adaptSubSelects = ({ SELECT: { from, where } }, scenario) => {
1084
1084
  }
1085
1085
  } else if (element.SELECT) {
1086
1086
  _adaptSubSelects(element, scenario)
1087
+ } else if (element.xpr) {
1088
+ for (const ele of element.xpr.filter(e => e.SELECT)) {
1089
+ _adaptSubSelects(ele, scenario)
1090
+ }
1087
1091
  }
1088
1092
  }
1089
1093
  }
@@ -19,7 +19,7 @@ const astToColumns = selections => {
19
19
 
20
20
  const filter = getArgumentByName(selection.arguments, ARGUMENT.FILTER)
21
21
  if (filter) {
22
- column.where = astToWhere(filter).xpr
22
+ column.where = astToWhere(filter)
23
23
  }
24
24
 
25
25
  const orderBy = getArgumentByName(selection.arguments, ARGUMENT.ORDER_BY)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sap/cds",
3
- "version": "5.7.1",
3
+ "version": "5.7.2",
4
4
  "description": "SAP Cloud Application Programming Model - CDS for Node.js",
5
5
  "homepage": "https://cap.cloud.sap/",
6
6
  "keywords": [