@sap/cds-compiler 3.9.6 → 3.9.8
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 +9 -0
- package/lib/base/message-registry.js +4 -0
- package/lib/checks/manyNavigations.js +33 -0
- package/lib/checks/validator.js +2 -1
- package/lib/edm/edm.js +1 -1
- package/lib/edm/edmPreprocessor.js +6 -2
- package/lib/edm/edmUtils.js +8 -8
- package/lib/transform/db/applyTransformations.js +1 -1
- package/lib/transform/forOdataNew.js +4 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,15 @@
|
|
|
7
7
|
Note: `beta` fixes, changes and features are usually not listed in this ChangeLog but [here](doc/CHANGELOG_BETA.md).
|
|
8
8
|
The compiler behavior concerning `beta` features can change at any time without notice.
|
|
9
9
|
|
|
10
|
+
## Version 3.9.8 - 2023-08-03
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- to.edm(x):
|
|
15
|
+
+ Don't expand `@mandatory` if element has an annotation with prefix `@Common.FieldControl.`.
|
|
16
|
+
+ Fix a bug when referencing nested many structures, especially referring to a managed association via
|
|
17
|
+
`$self` comparison.
|
|
18
|
+
- to.sql/hdi/hdbcds: Detect navigation into arrayed structures and raise helpful errors instead of running into internal errors.
|
|
10
19
|
|
|
11
20
|
## Version 3.9.6 - 2023-07-27
|
|
12
21
|
|
|
@@ -116,6 +116,7 @@ const centralMessages = {
|
|
|
116
116
|
'type-ambiguous-target': { severity: 'Warning' },
|
|
117
117
|
|
|
118
118
|
'ref-autoexposed': { severity: 'Error', configurableFor: 'deprecated' },
|
|
119
|
+
'ref-unexpected-many-navigation': { severity: 'Error' },
|
|
119
120
|
// Published! Used in @sap/cds-lsp; if renamed, add to oldMessageIds and contact colleagues
|
|
120
121
|
'ref-undefined-art': { severity: 'Error' },
|
|
121
122
|
'ref-undefined-def': { severity: 'Error' },
|
|
@@ -521,6 +522,9 @@ const centralMessageTexts = {
|
|
|
521
522
|
std: '$(ART) can\'t be extended because it originates from an include',
|
|
522
523
|
elements: '$(ART) can\'t be extended by elements/enums because it originates from an include',
|
|
523
524
|
},
|
|
525
|
+
'ref-unexpected-many-navigation': {
|
|
526
|
+
std: 'Unexpected navigation into arrayed structure',
|
|
527
|
+
},
|
|
524
528
|
'ref-unexpected-scope': {
|
|
525
529
|
std: 'Unexpected parameter reference',
|
|
526
530
|
calc: 'Calculated elements can\'t use parameter references',
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { applyTransformationsOnNonDictionary } = require('../model/csnUtils');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Check all refs in the given parent for the traversal of paths
|
|
7
|
+
* into `.items`
|
|
8
|
+
*
|
|
9
|
+
* @param {object} parent Object with the expression as a property
|
|
10
|
+
* @param {string} propOnParent Name of the expression property on parent
|
|
11
|
+
* @param {Array} e Expression to check - see module.exports
|
|
12
|
+
* @param {CSN.Path} path
|
|
13
|
+
*/
|
|
14
|
+
function navigationIntoMany( parent, propOnParent, e, path ) {
|
|
15
|
+
applyTransformationsOnNonDictionary(parent, propOnParent, {
|
|
16
|
+
ref: (_parent, _prop, ref, _path) => {
|
|
17
|
+
const itemNavigationIndex = _parent._links?.findIndex(l => l.art.items);
|
|
18
|
+
if (itemNavigationIndex !== -1 && _parent.ref.length > itemNavigationIndex + 1)
|
|
19
|
+
this.message('ref-unexpected-many-navigation', _path);
|
|
20
|
+
},
|
|
21
|
+
}, { skipStandard: { type: true } }, path);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
module.exports = {
|
|
25
|
+
columns: navigationIntoMany,
|
|
26
|
+
from: navigationIntoMany,
|
|
27
|
+
on: navigationIntoMany,
|
|
28
|
+
having: navigationIntoMany,
|
|
29
|
+
groupBy: navigationIntoMany,
|
|
30
|
+
orderBy: navigationIntoMany,
|
|
31
|
+
where: navigationIntoMany,
|
|
32
|
+
xpr: navigationIntoMany,
|
|
33
|
+
};
|
package/lib/checks/validator.js
CHANGED
|
@@ -11,6 +11,7 @@ const enrich = require('./enricher');
|
|
|
11
11
|
const { validateSelectItems } = require('./selectItems');
|
|
12
12
|
const { rejectParamDefaultsInHanaCds, warnAboutDefaultOnAssociationForHanaCds } = require('./defaultValues');
|
|
13
13
|
const validateCdsPersistenceAnnotation = require('./cdsPersistence');
|
|
14
|
+
const navigationIntoMany = require('./manyNavigations');
|
|
14
15
|
const checkUsedTypesForAnonymousAspectComposition = require('./managedInType');
|
|
15
16
|
const validateHasPersistedElements = require('./hasPersistedElements');
|
|
16
17
|
const checkForHanaTypes = require('./checkForTypes');
|
|
@@ -71,7 +72,7 @@ const forRelationalDBArtifactValidators
|
|
|
71
72
|
checkSqlAnnotationOnArtifact,
|
|
72
73
|
];
|
|
73
74
|
|
|
74
|
-
const forRelationalDBCsnValidators = [ nonexpandableStructuredInExpression ];
|
|
75
|
+
const forRelationalDBCsnValidators = [ nonexpandableStructuredInExpression, navigationIntoMany ];
|
|
75
76
|
/**
|
|
76
77
|
* @type {Array<(query: CSN.Query, path: CSN.Path) => void>}
|
|
77
78
|
*/
|
package/lib/edm/edm.js
CHANGED
|
@@ -1118,7 +1118,7 @@ function getEdm(options, messageFunctions) {
|
|
|
1118
1118
|
: undefined;
|
|
1119
1119
|
if(partner && partner['@odata.navigable'] !== false && this._csn._edmParentCsn.kind !== 'type') {
|
|
1120
1120
|
// $abspath[0] is main entity
|
|
1121
|
-
this._edmAttributes.Partner = partner.$abspath.slice(1).join(
|
|
1121
|
+
this._edmAttributes.Partner = partner.$abspath.slice(1).join('/');
|
|
1122
1122
|
}
|
|
1123
1123
|
|
|
1124
1124
|
/*
|
|
@@ -657,9 +657,13 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
|
|
|
657
657
|
env = env[ps];
|
|
658
658
|
if (env && env.constructor === Object) {
|
|
659
659
|
path.push(ps);
|
|
660
|
-
if
|
|
660
|
+
// jump over many items but not if this is an element
|
|
661
|
+
if (env.items) {
|
|
661
662
|
env = env.items;
|
|
662
|
-
|
|
663
|
+
if (p[i + 1] === 'items')
|
|
664
|
+
i++;
|
|
665
|
+
}
|
|
666
|
+
if (env.type && !isBuiltinType(env.type) && !env.elements)
|
|
663
667
|
env = csn.definitions[env.type];
|
|
664
668
|
}
|
|
665
669
|
}
|
package/lib/edm/edmUtils.js
CHANGED
|
@@ -764,14 +764,14 @@ function getBaseName(name) {
|
|
|
764
764
|
}
|
|
765
765
|
|
|
766
766
|
// This is a poor mans path resolver for $self partner paths only
|
|
767
|
-
function resolveOriginAssoc(csn, env, path) {
|
|
768
|
-
for(const segment of path) {
|
|
769
|
-
|
|
770
|
-
if(elements)
|
|
771
|
-
env =
|
|
772
|
-
|
|
773
|
-
if(type && !isBuiltinType(type) && !(env
|
|
774
|
-
env = csn.definitions[
|
|
767
|
+
function resolveOriginAssoc( csn, env, path ) {
|
|
768
|
+
for (const segment of path) {
|
|
769
|
+
const elements = (env?.items?.elements || env?.elements);
|
|
770
|
+
if (elements)
|
|
771
|
+
env = elements[segment];
|
|
772
|
+
const type = (env?.items?.type || env?.type);
|
|
773
|
+
if (type && !isBuiltinType(type) && !(env?.items?.elements || env?.elements))
|
|
774
|
+
env = csn.definitions[type];
|
|
775
775
|
}
|
|
776
776
|
return env;
|
|
777
777
|
}
|
|
@@ -52,7 +52,7 @@ function applyTransformationsInternal( parent, prop, customTransformers, artifac
|
|
|
52
52
|
* The customTransformers are applied here (and only here).
|
|
53
53
|
*
|
|
54
54
|
* @param {object | Array} _parent the thing that has _prop
|
|
55
|
-
* @param {string|number} _prop the name of the current property
|
|
55
|
+
* @param {string|number} _prop the name of the current property or index
|
|
56
56
|
* @param {object} node The value of node[_prop]
|
|
57
57
|
*/
|
|
58
58
|
function standard( _parent, _prop, node ) {
|
|
@@ -366,9 +366,11 @@ function transform4odataWithCsn(inputModel, options) {
|
|
|
366
366
|
setAnnotation(node, '@Capabilities.UpdateRestrictions.Updatable', false);
|
|
367
367
|
}
|
|
368
368
|
}
|
|
369
|
-
|
|
369
|
+
|
|
370
|
+
// Only on element level: translate @mandatory
|
|
370
371
|
if (node['@mandatory'] &&
|
|
371
|
-
|
|
372
|
+
node.kind === undefined &&
|
|
373
|
+
!Object.entries(node).some(([k,v]) => k === '@Common.FieldControl' || k.startsWith('@Common.FieldControl.') && v != null)) {
|
|
372
374
|
setAnnotation(node, '@Common.FieldControl', { '#': 'Mandatory' });
|
|
373
375
|
}
|
|
374
376
|
|