@sap/cds-compiler 3.1.0 → 3.1.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 +10 -0
- package/lib/edm/annotations/genericTranslation.js +12 -2
- package/lib/edm/edmPreprocessor.js +34 -17
- package/lib/edm/edmUtils.js +12 -15
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,16 @@
|
|
|
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.1.2 - 2022-08-19
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- to.edm(x):
|
|
15
|
+
+ `@Capabilities` 'pull up' for containment trees should not prefix the
|
|
16
|
+
dynamic annotation paths of the root container.
|
|
17
|
+
+ Remove service namespace prefix of a parameter type for function/action annotation targets
|
|
18
|
+
in multi schema mode if the parameter type is defined in an alternative schema.
|
|
19
|
+
|
|
10
20
|
## Version 3.1.0 - 2022-08-04
|
|
11
21
|
|
|
12
22
|
### Added
|
|
@@ -401,8 +401,6 @@ function csn2annotationEdm(csn, serviceName, Edm = undefined, options=undefined,
|
|
|
401
401
|
params.push(action['@cds.odata.bindingparameter.collection'] ? 'Collection(' + bindingParam + ')' : bindingParam);
|
|
402
402
|
}
|
|
403
403
|
if (action.kind === 'function') {
|
|
404
|
-
let mapType = (p) => (isBuiltinType(p.type)) ?
|
|
405
|
-
edmUtils.mapCdsToEdmType(p, messageFunctions, false /*is only called for v4*/) : p.type;
|
|
406
404
|
if(action.params) {
|
|
407
405
|
action.params && Object.values(action.params).forEach(p => {
|
|
408
406
|
let isArrayType = !p.type && p.items && p.items.type;
|
|
@@ -411,6 +409,18 @@ function csn2annotationEdm(csn, serviceName, Edm = undefined, options=undefined,
|
|
|
411
409
|
}
|
|
412
410
|
}
|
|
413
411
|
return '(' + params.join(',') + ')';
|
|
412
|
+
|
|
413
|
+
function mapType(p) {
|
|
414
|
+
if(isBuiltinType(p.type))
|
|
415
|
+
return edmUtils.mapCdsToEdmType(p, messageFunctions, false /*is only called for v4*/)
|
|
416
|
+
else if(options.whatsMySchemaName) {
|
|
417
|
+
const schemaName = options.whatsMySchemaName(p.type);
|
|
418
|
+
// strip the service namespace of from a parameter type
|
|
419
|
+
if(schemaName && schemaName !== options.serviceName)
|
|
420
|
+
return p.type.replace(options.serviceName + '.', '');
|
|
421
|
+
}
|
|
422
|
+
return p.type;
|
|
423
|
+
}
|
|
414
424
|
}
|
|
415
425
|
|
|
416
426
|
|
|
@@ -4,7 +4,7 @@ const { setProp, isDeprecatedEnabled, isBetaEnabled } = require('../base/model')
|
|
|
4
4
|
const {
|
|
5
5
|
forEachDefinition, forEachGeneric, forEachMemberRecursively,
|
|
6
6
|
isEdmPropertyRendered, getUtils, cloneCsnNonDict, cloneCsnDictionary,
|
|
7
|
-
isBuiltinType,
|
|
7
|
+
isBuiltinType, applyTransformations
|
|
8
8
|
} = require('../model/csnUtils');
|
|
9
9
|
const edmUtils = require('./edmUtils.js');
|
|
10
10
|
const edmAnnoPreproc = require('./edmAnnoPreprocessor.js');
|
|
@@ -1833,21 +1833,51 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
|
|
|
1833
1833
|
// copy or create container restrictions, don't modify original
|
|
1834
1834
|
const localRestrictions = container[NavResAnno] ?
|
|
1835
1835
|
cloneCsnDictionary(container[NavResAnno], options) : []
|
|
1836
|
-
|
|
1836
|
+
|
|
1837
|
+
// prefix the existing navigation property restritictions on the container
|
|
1838
|
+
if(prefix.length) {
|
|
1839
|
+
localRestrictions.forEach(npe => {
|
|
1840
|
+
if(npe.NavigationProperty &&
|
|
1841
|
+
npe.NavigationProperty['='] &&
|
|
1842
|
+
typeof npe.NavigationProperty['='] === 'string') {
|
|
1843
|
+
applyTransformations({ definitions: { npe }}, {
|
|
1844
|
+
"=": (parent, prop, value) => {
|
|
1845
|
+
parent[prop] = prefix.concat(value).join('.');
|
|
1846
|
+
}
|
|
1847
|
+
});
|
|
1848
|
+
}
|
|
1849
|
+
});
|
|
1850
|
+
}
|
|
1851
|
+
|
|
1837
1852
|
setProp(container, '$visited', true);
|
|
1853
|
+
// collect capabilities from containees
|
|
1838
1854
|
container.$containeeAssociations.forEach(entry => {
|
|
1839
1855
|
const { assoc, path } = entry;
|
|
1840
1856
|
const containee = assoc._target;
|
|
1841
1857
|
|
|
1842
1858
|
if(isMyServiceRequested(containee.name) || containee.$proxy) {
|
|
1843
1859
|
const localAssocPath = path.join('.');
|
|
1860
|
+
let navPropEntry;
|
|
1861
|
+
const hasEntry = !!(navPropEntry = localRestrictions.find(p =>
|
|
1862
|
+
p.NavigationProperty && p.NavigationProperty['='] === prefix.concat(localAssocPath).join('.')));
|
|
1863
|
+
|
|
1864
|
+
if(!hasEntry) {
|
|
1865
|
+
navPropEntry = { NavigationProperty: { '=': prefix.concat(localAssocPath).join('.') } };
|
|
1866
|
+
}
|
|
1867
|
+
|
|
1844
1868
|
const props = Object.entries(containee);
|
|
1869
|
+
let newEntry = false;
|
|
1845
1870
|
['@Capabilities.DeleteRestrictions',
|
|
1846
1871
|
'@Capabilities.InsertRestrictions',
|
|
1847
1872
|
'@Capabilities.UpdateRestrictions',
|
|
1848
|
-
'@Capabilities.ReadRestrictions'].forEach(c =>
|
|
1849
|
-
edmUtils.
|
|
1873
|
+
'@Capabilities.ReadRestrictions'].forEach(c => {
|
|
1874
|
+
if(edmUtils.mergeIntoNavPropEntry(c, navPropEntry, prefix.concat(path), props))
|
|
1875
|
+
newEntry = true;
|
|
1876
|
+
});
|
|
1850
1877
|
|
|
1878
|
+
if(newEntry && !hasEntry) {
|
|
1879
|
+
localRestrictions.push(navPropEntry);
|
|
1880
|
+
}
|
|
1851
1881
|
|
|
1852
1882
|
if(!containee.$visited) {
|
|
1853
1883
|
addContainmentAnnotationsRecursively(prefix.concat(path), containee);
|
|
@@ -1855,19 +1885,6 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
|
|
|
1855
1885
|
}
|
|
1856
1886
|
});
|
|
1857
1887
|
|
|
1858
|
-
// prefix all paths in the navPropEntry with the NavigationPropertyPath
|
|
1859
|
-
localRestrictions.forEach((p, i) => {
|
|
1860
|
-
if(p.NavigationProperty && p.NavigationProperty['='] && typeof p.NavigationProperty['='] === 'string') {
|
|
1861
|
-
const lp = [ ...prefix, p.NavigationProperty['=']].join('.');
|
|
1862
|
-
applyTransformationsOnNonDictionary(localRestrictions, i, {
|
|
1863
|
-
"=": (parent, prop, value) => {
|
|
1864
|
-
parent[prop] = [lp, value].join('.');
|
|
1865
|
-
}
|
|
1866
|
-
});
|
|
1867
|
-
// reset NavigationPropertyPath
|
|
1868
|
-
p.NavigationProperty['='] = lp;
|
|
1869
|
-
}
|
|
1870
|
-
});
|
|
1871
1888
|
rootRestrictions.unshift(...localRestrictions);
|
|
1872
1889
|
delete container.$visited;
|
|
1873
1890
|
}
|
package/lib/edm/edmUtils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
const { setProp } = require('../base/model');
|
|
3
|
-
const { isBuiltinType, isEdmPropertyRendered } = require('../model/csnUtils');
|
|
3
|
+
const { isBuiltinType, isEdmPropertyRendered, applyTransformations } = require('../model/csnUtils');
|
|
4
4
|
const { escapeString, hasControlCharacters, hasUnpairedUnicodeSurrogate } = require("../render/utils/stringEscapes");
|
|
5
5
|
|
|
6
6
|
/* eslint max-statements-per-line:off */
|
|
@@ -753,24 +753,23 @@ function resolveOriginAssoc(csn, env, path) {
|
|
|
753
753
|
return env;
|
|
754
754
|
}
|
|
755
755
|
|
|
756
|
-
function
|
|
757
|
-
let navPropEntry;
|
|
758
|
-
let hasEntry = false;
|
|
756
|
+
function mergeIntoNavPropEntry(annoPrefix, navPropEntry, prefix, props) {
|
|
759
757
|
let newEntry = false;
|
|
760
|
-
hasEntry = !!(navPropEntry = navPropRestrictions.find(p =>
|
|
761
|
-
p.NavigationProperty && p.NavigationProperty['='] === assocPath));
|
|
762
758
|
|
|
763
|
-
if(!hasEntry) {
|
|
764
|
-
navPropEntry = { NavigationProperty: { '=': assocPath } };
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
const prop = annoPrefix.split('.')[1];
|
|
768
759
|
// Filter properties with prefix and reduce them into a new dictionary
|
|
769
760
|
const o = props.filter(p => p[0].startsWith(annoPrefix+'.')).reduce((a,c) => {
|
|
770
761
|
a[c[0].replace(annoPrefix+'.', '')] = c[1];
|
|
771
762
|
return a;
|
|
772
763
|
}, { });
|
|
764
|
+
|
|
765
|
+
// BEFORE merging found capabilities, prefix the paths
|
|
766
|
+
applyTransformations({ definitions: { o }}, {
|
|
767
|
+
"=": (parent, prop, value) => {
|
|
768
|
+
parent[prop] = prefix.concat(value).join('.');
|
|
769
|
+
}
|
|
770
|
+
});
|
|
773
771
|
// don't overwrite existing restrictions
|
|
772
|
+
const prop = annoPrefix.split('.')[1];
|
|
774
773
|
if(!navPropEntry[prop]) {
|
|
775
774
|
// if dictionary has entries, add them to navPropEnty
|
|
776
775
|
if(Object.keys(o).length) {
|
|
@@ -807,9 +806,7 @@ function mergeIntoNavPropRestrictions(annoPrefix, assocPath, props, navPropRestr
|
|
|
807
806
|
navPropEntry[prop][k] = v;
|
|
808
807
|
});
|
|
809
808
|
}
|
|
810
|
-
|
|
811
|
-
navPropRestrictions.push(navPropEntry);
|
|
812
|
-
}
|
|
809
|
+
return newEntry;
|
|
813
810
|
}
|
|
814
811
|
|
|
815
812
|
// Assign but not overwrite annotation
|
|
@@ -854,5 +851,5 @@ module.exports = {
|
|
|
854
851
|
escapeStringForText,
|
|
855
852
|
getSchemaPrefix,
|
|
856
853
|
getBaseName,
|
|
857
|
-
|
|
854
|
+
mergeIntoNavPropEntry
|
|
858
855
|
}
|