@sap/cds-compiler 3.9.2 → 3.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/lib/base/message-registry.js +1 -1
- package/lib/edm/annotations/genericTranslation.js +12 -2
- package/lib/edm/csn2edm.js +13 -13
- package/lib/json/from-csn.js +2 -2
- package/lib/transform/localized.js +1 -1
- package/lib/utils/file.js +3 -3
- package/lib/utils/moduleResolve.js +1 -1
- 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.9.4 - 2023-06-07
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- compiler: `USING` empty files were incorrectly marked as "not found".
|
|
15
|
+
- Localized convenience views for projections (not views) did not have references rewritten.
|
|
16
|
+
This only affects CSN, the SQL result was correct.
|
|
17
|
+
- to.edm(x): Render correct EntitySetPath and annotation target path for actions/functions
|
|
18
|
+
with explicit binding parameter.
|
|
19
|
+
|
|
10
20
|
## Version 3.9.2 - 2023-04-27
|
|
11
21
|
|
|
12
22
|
### Fixed
|
|
@@ -391,7 +391,7 @@ const centralMessageTexts = {
|
|
|
391
391
|
'syntax-deprecated-value': { // Warning
|
|
392
392
|
std: 'Deprecated representation of the value in property $(PROP)',
|
|
393
393
|
replace: 'Replace value in $(PROP) by $(VALUE)',
|
|
394
|
-
'zero-parens': 'Deprecated CSN
|
|
394
|
+
'zero-parens': 'Deprecated CSN v0.1.0 representation of expressions in parentheses',
|
|
395
395
|
'zero-replace': 'Replace CSN v0.1.0 value in $(PROP) by $(VALUE)',
|
|
396
396
|
},
|
|
397
397
|
'syntax-deprecated-type-ref': {
|
|
@@ -416,9 +416,19 @@ function csn2annotationEdm(reqDefs, csnVocabularies, serviceName,
|
|
|
416
416
|
function relParList() {
|
|
417
417
|
// we rely on the order of params in the csn being the correct one
|
|
418
418
|
const params = [];
|
|
419
|
-
if (entityNameIfBound
|
|
420
|
-
|
|
419
|
+
if (entityNameIfBound) {
|
|
420
|
+
// If this is an action and has an explicit binding parameter add it here
|
|
421
|
+
if(cAction.$bindingParam && cAction.kind === 'action') {
|
|
422
|
+
params.push(cAction.$bindingParam.items ? 'Collection(' + entityNameIfBound + ')' : entityNameIfBound);
|
|
423
|
+
}
|
|
424
|
+
// If action/function has no explicit binding parameter add it here
|
|
425
|
+
else if (!cAction.$bindingParam) {
|
|
426
|
+
params.push(cAction['@cds.odata.bindingparameter.collection'] ? 'Collection(' + entityNameIfBound + ')' : entityNameIfBound);
|
|
427
|
+
}
|
|
421
428
|
}
|
|
429
|
+
// In case this is a function the explicit binding parameter is part of
|
|
430
|
+
// the functions params dictionary. Only for functions all parameters must
|
|
431
|
+
// be listed in the annotation target
|
|
422
432
|
if (cAction.kind === 'function') {
|
|
423
433
|
if(cAction.params) {
|
|
424
434
|
cAction.params && Object.values(cAction.params).forEach(p => {
|
package/lib/edm/csn2edm.js
CHANGED
|
@@ -687,14 +687,15 @@ function csn2edmAll(_csn, _options, serviceNames=undefined) {
|
|
|
687
687
|
The binding parameter remains in the CSN and is rendered as any other
|
|
688
688
|
parameter (including default value/not null/ etc) and acts as annotation carrier.
|
|
689
689
|
*/
|
|
690
|
-
|
|
690
|
+
|
|
691
|
+
let bpName = 'in';
|
|
691
692
|
if(actionCsn.params) {
|
|
692
693
|
const entries = Object.entries(actionCsn.params);
|
|
693
694
|
const firstParam = entries[0][1];
|
|
694
695
|
const type = firstParam?.items?.type || firstParam?.type;
|
|
695
696
|
if(type === special$self) {
|
|
696
|
-
|
|
697
|
-
|
|
697
|
+
bpName = entries[0][0];
|
|
698
|
+
setProp(actionCsn, '$bindingParam', firstParam);
|
|
698
699
|
if(bpType) {
|
|
699
700
|
if(firstParam.items?.type)
|
|
700
701
|
firstParam.items.type = bpType;
|
|
@@ -707,16 +708,15 @@ function csn2edmAll(_csn, _options, serviceNames=undefined) {
|
|
|
707
708
|
}
|
|
708
709
|
|
|
709
710
|
// bpName is eventually used later for EntitySetPath
|
|
710
|
-
const bpNameAnno = actionCsn['@cds.odata.bindingparameter.name'];
|
|
711
|
-
let bpName = 'in';
|
|
712
|
-
if(bpNameAnno != null) {
|
|
713
|
-
if(typeof bpNameAnno === 'string')
|
|
714
|
-
bpName = bpNameAnno;
|
|
715
|
-
if(typeof bpNameAnno === 'object' && bpNameAnno['='])
|
|
716
|
-
bpName = bpNameAnno['='];
|
|
717
|
-
}
|
|
718
711
|
// No explicit binding parameter, check (user defined) annotation value)
|
|
719
|
-
if(!actionCsn.$
|
|
712
|
+
if(!actionCsn.$bindingParam) {
|
|
713
|
+
const bpNameAnno = actionCsn['@cds.odata.bindingparameter.name'];
|
|
714
|
+
if(bpNameAnno != null) {
|
|
715
|
+
if(typeof bpNameAnno === 'string')
|
|
716
|
+
bpName = bpNameAnno;
|
|
717
|
+
if(typeof bpNameAnno === 'object' && bpNameAnno['='])
|
|
718
|
+
bpName = bpNameAnno['='];
|
|
719
|
+
}
|
|
720
720
|
if(!edmUtils.isODataSimpleIdentifier(bpName))
|
|
721
721
|
message('odata-spec-violation-id', [...loc, '@cds.odata.bindingparameter.name'], { id: bpName });
|
|
722
722
|
if(actionCsn.params && actionCsn.params[bpName]) {
|
|
@@ -726,7 +726,7 @@ function csn2edmAll(_csn, _options, serviceNames=undefined) {
|
|
|
726
726
|
if(entityCsn != undefined)
|
|
727
727
|
{
|
|
728
728
|
actionNode.setEdmAttribute('IsBound', true);
|
|
729
|
-
if(!actionCsn.$
|
|
729
|
+
if(!actionCsn.$bindingParam) {
|
|
730
730
|
// Binding Parameter: 'in' at first position in sequence, this is decisive!
|
|
731
731
|
if(actionCsn['@cds.odata.bindingparameter.collection'])
|
|
732
732
|
actionNode.append(new Edm.Parameter(v, { Name: bpName, Type: bpType, Collection:true/*, Nullable: false*/ } ));
|
package/lib/json/from-csn.js
CHANGED
|
@@ -1881,10 +1881,10 @@ function refSplit( name, prop ) {
|
|
|
1881
1881
|
return { path: path.map( id => ({ id, location: location() }) ), location: location() };
|
|
1882
1882
|
}
|
|
1883
1883
|
|
|
1884
|
-
function replaceZeroValue( spec, msgVariant,
|
|
1884
|
+
function replaceZeroValue( spec, msgVariant, newValue ) {
|
|
1885
1885
|
if (!csnVersionZero && !spec.vZeroFor) {
|
|
1886
1886
|
warning( 'syntax-deprecated-value', location(true),
|
|
1887
|
-
{ '#': msgVariant, prop: spec.msgProp,
|
|
1887
|
+
{ '#': msgVariant, prop: spec.msgProp, value: newValue } );
|
|
1888
1888
|
}
|
|
1889
1889
|
}
|
|
1890
1890
|
|
|
@@ -511,7 +511,7 @@ function _addLocalizationViews(csn, options, useJoins, config) {
|
|
|
511
511
|
// For view convenience views (i.e. transitive views) we need to rewrite `from`
|
|
512
512
|
// references as well as need to handle `mixin` elements.
|
|
513
513
|
// a.k.a 'LOCALIZED-VERTICAL'
|
|
514
|
-
forAllQueries(art.query || art.projection, (query) => {
|
|
514
|
+
forAllQueries(art.query || { SELECT: art.projection }, (query) => {
|
|
515
515
|
query = query.SELECT || query.SET || query;
|
|
516
516
|
if (query.from)
|
|
517
517
|
rewriteFrom(query.from);
|
package/lib/utils/file.js
CHANGED
|
@@ -140,12 +140,12 @@ function cdsFs( fileCache, enableTrace ) {
|
|
|
140
140
|
traceFS( 'ISFILE:cache:', filename, body );
|
|
141
141
|
if (body instanceof Error)
|
|
142
142
|
cb( body ); // no need for process.nextTick( cb, body ) with moduleResolve
|
|
143
|
-
else
|
|
144
|
-
cb( null, !!body );
|
|
143
|
+
else // body could be empty string
|
|
144
|
+
cb( null, !!body || typeof body === 'string');
|
|
145
145
|
}
|
|
146
146
|
else {
|
|
147
147
|
traceFS( 'ISFILE:start:', filename, body );
|
|
148
|
-
// in the future (if we do module resolve
|
|
148
|
+
// in the future (if we do module resolve ourselves with just readFile),
|
|
149
149
|
// we avoid parallel readFile by storing having an array of `cb`s in
|
|
150
150
|
// fileCache[ filename ] before starting fs.readFile().
|
|
151
151
|
try {
|
|
@@ -213,7 +213,7 @@ function resolveCDS( moduleName, options, callback ) {
|
|
|
213
213
|
options.realpath(resolvedBaseDir, (realPathErr, realPath) => {
|
|
214
214
|
// There may be an error in resolving the symlink.
|
|
215
215
|
// We ignore the error and simply use the original path.
|
|
216
|
-
// Otherwise cds-lsp tests would fail because they don't have real
|
|
216
|
+
// Otherwise, cds-lsp tests would fail because they don't have real
|
|
217
217
|
// files in their tests.
|
|
218
218
|
if (!realPathErr)
|
|
219
219
|
resolvedBaseDir = realPath;
|