@sap/cds-compiler 3.4.0 → 3.4.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
@@ -7,11 +7,23 @@
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.4.2 - 2022-11-11
11
+
12
+ ### Fixed
13
+
14
+ - Don't propagate `@cds.external` (The CDS Importer adds `@cds.external` for all
15
+ imported definitions beginning with cds-dk@6.3.0, see CAP release log).
16
+ - for.odata: Ignore all `@cds.external` definitions.
17
+ - to.sql: For sql dialect `h2`, don't turn a Decimal with length 0 into a Decfloat.
18
+ - Extending a projection with an aspect could result in incorrect auto-redirection.
19
+ - Annotations of aspects were not properly propagated to projections under some order-specific circumstances.
20
+
10
21
  ## Version 3.4.0 - 2022-10-26
11
22
 
12
23
  ### Added
13
24
 
14
- - to.sql: Add support for sql dialect `h2`, which renders SQL for H2 2.x
25
+ - to.sql: Add support for sql dialect `h2`, which renders SQL for H2 2.x.
26
+ - Projections can now be extended by annotation-only aspects, e.g. `extend P with MyAspect;`.
15
27
 
16
28
  ### Fixed
17
29
 
@@ -98,7 +98,7 @@ const centralMessages = {
98
98
  'ref-sloppy-target': { severity: 'Warning' },
99
99
 
100
100
  'extend-repeated-intralayer': { severity: 'Warning' },
101
- 'extend-unrelated-layer': { severity: 'Warning' },
101
+ 'extend-unrelated-layer': { severity: 'Info' },
102
102
 
103
103
  'ext-duplicate-extend-type': { severity: 'Error' },
104
104
  'ext-duplicate-extend-type-unrelated-layer': { severity: 'Error', configurableFor: true },
@@ -620,15 +620,17 @@ function extend( model ) {
620
620
  return;
621
621
  }
622
622
 
623
- if (!art._ancestors)
624
- setLink( art, '_ancestors', [] ); // recursive array of includes
625
- for (const ref of ext.includes) {
626
- const template = ref._artifact;
627
- // !template -> non-includable, e.g. scalar type, or cyclic
628
- if (template) {
629
- if (template._ancestors)
630
- art._ancestors.push( ...template._ancestors );
631
- art._ancestors.push( template );
623
+ if (!art.query) {
624
+ if (!art._ancestors)
625
+ setLink( art, '_ancestors', [] ); // recursive array of includes
626
+ for (const ref of ext.includes) {
627
+ const template = ref._artifact;
628
+ // !template -> non-includable, e.g. scalar type, or cyclic
629
+ if (template) {
630
+ if (template._ancestors)
631
+ art._ancestors.push( ...template._ancestors );
632
+ art._ancestors.push( template );
633
+ }
632
634
  }
633
635
  }
634
636
  includeMembers( ext, art, 'elements' );
@@ -1275,7 +1277,7 @@ function copyPersistenceAnnotations(target, source, options) {
1275
1277
  copy( '@cds.persistence.exists' );
1276
1278
  copy( '@cds.persistence.skip' );
1277
1279
 
1278
- function copy(anno) {
1280
+ function copy( anno ) {
1279
1281
  if ( source[anno] && !target[anno] )
1280
1282
  target[anno] = { ...source[anno], $inferred: 'parent-origin' };
1281
1283
  }
@@ -33,6 +33,7 @@ function propagate( model ) {
33
33
  '@Analytics.visible': never,
34
34
  '@cds.autoexpose': onlyViaArtifact,
35
35
  '@cds.autoexposed': never, // in case people set it themselves
36
+ '@cds.external': never,
36
37
  '@cds.redirection.target': never,
37
38
  '@fiori.draft.enabled': onlyViaArtifact,
38
39
  '@': annotation, // always except in 'returns' and 'items'
@@ -84,42 +85,34 @@ function propagate( model ) {
84
85
  return;
85
86
  }
86
87
  // console.log('RUN:', art.name, art.elements ? Object.keys(art.elements) : 0)
88
+
87
89
  const chain = [];
88
- let target = art;
89
- let source = getOrigin( target );
90
- while (source && checkAndSetStatus( source )) {
91
- chain.push({ target, source });
92
- target = source;
93
- source = getOrigin( target );
94
- }
95
- if (source) { // the source has fully propagated properties
96
- chain.push({ target, source });
97
- }
98
- else if (target._main) { // source is element, which has not inherited props yet
99
- run( target._main ); // run on main artifact first
100
- }
90
+ let targets = [ art ];
91
+ while (targets.length) {
92
+ const news = [];
93
+ for (const target of targets) {
94
+ const origin = getOrigin( target );
95
+ if (origin) {
96
+ chain.push( { target, source: origin } );
97
+ if (checkAndSetStatus( origin ))
98
+ news.push( origin );
99
+ }
101
100
 
102
- // Even with a query source, go through `includes`. `source` is propagated first, i.e. wins.
103
- if (target.includes) {
104
- let targets = [ target ];
105
- while (targets.length) {
106
- const news = [];
107
- for (const t of targets) {
108
- for (const ref of t.includes || []) {
109
- const s = ref._artifact;
110
- if (!s) // ref error
111
- continue;
112
- chain.push( { target: t, source: s } );
113
- if (checkAndSetStatus( s ))
114
- news.push( s );
115
- }
101
+ for (const ref of target.includes || []) {
102
+ const include = ref._artifact;
103
+ if (!include)
104
+ continue;
105
+ chain.push( { target, source: include } );
106
+ if (checkAndSetStatus( include ))
107
+ news.push( include );
116
108
  }
117
- targets = news;
118
109
  }
110
+ targets = news;
119
111
  }
112
+
120
113
  chain.reverse().forEach( step );
121
114
  runMembers( art );
122
- // console.log('DONE:', art.name, art.elements ? Object.keys(art.elements) : 0)
115
+ // console.log('DONE:', art.name, art.elements ? Object.keys(art.elements) : 0);
123
116
  }
124
117
 
125
118
  function runMembers( art ) {
@@ -109,7 +109,9 @@ function transform4odataWithCsn(inputModel, options) {
109
109
  // @ts-ignore
110
110
  const externalServices = services.filter(serviceName => csn.definitions[serviceName]['@cds.external']);
111
111
  // @ts-ignore
112
- const isExternalServiceMember = (_art, name) => externalServices.includes(getServiceName(name));
112
+ const isExternalServiceMember = (art, name) => {
113
+ return !!(externalServices.includes(getServiceName(name)) || (art && art['@cds.external']))
114
+ }
113
115
 
114
116
  if (options.csnFlavor === 'universal' && isBetaEnabled(options, 'enableUniversalCsn'))
115
117
  enrichUniversalCsn(csn, options);
@@ -163,10 +165,12 @@ function transform4odataWithCsn(inputModel, options) {
163
165
  // Needs to happen exactly between flattenAllStructStepsInRefs and flattenElements to keep model resolvable.
164
166
  // OData doesn't resolve type chains after the first 'items'
165
167
  flattening.resolveTypeReferences(csn, options, resolved, '_',
166
- { skip: [ 'action', 'aspect', 'event', 'function', 'type'], skipArtifact: isExternalServiceMember, skipStandard: { items: true } });
168
+ { skip: [ 'action', 'aspect', 'event', 'function', 'type'],
169
+ skipArtifact: isExternalServiceMember, skipStandard: { items: true } });
167
170
  // No structured elements exists anymore
168
171
  flattening.flattenElements(csn, options, '_', error,
169
- { skip: ['action', 'aspect', 'event', 'function', 'type'], skipArtifact: isExternalServiceMember,
172
+ { skip: ['action', 'aspect', 'event', 'function', 'type'],
173
+ skipArtifact: isExternalServiceMember,
170
174
  skipStandard: { items: true }, // don't drill further into .items
171
175
  skipDict: { actions: true } }); // don't drill further into .actions -> bound actions, action-artifacts are handled by skip
172
176
  }
@@ -705,7 +705,7 @@ function transformForRelationalDBWithCsn(inputModel, options, moduleName) {
705
705
  setProp(node, '$renamed', 'cds.UUID');
706
706
  }
707
707
 
708
- if(options.sqlDialect === 'h2' && val === 'cds.Decimal' && !node.scale) {
708
+ if(options.sqlDialect === 'h2' && val === 'cds.Decimal' && node.scale === undefined) {
709
709
  node[key] = 'cds.DecimalFloat'; // cds.Decimal and cds.Decimal(p) should map do DECFLOAT for h2
710
710
  }
711
711
 
@@ -28,6 +28,7 @@ module.exports = (csn, options) => {
28
28
  // Properties on definition level that we treat specially.
29
29
  const definitionPropagationRules = {
30
30
  '@cds.autoexpose': onlyViaArtifact,
31
+ '@cds.external': skip,
31
32
  '@fiori.draft.enabled': onlyViaArtifact,
32
33
  '@': nullStopsPropagation,
33
34
  // Example: `type E : F;` does not have `elements`, but they are required for e.g. OData.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sap/cds-compiler",
3
- "version": "3.4.0",
3
+ "version": "3.4.2",
4
4
  "description": "CDS (Core Data Services) compiler and backends",
5
5
  "homepage": "https://cap.cloud.sap/",
6
6
  "author": "SAP SE (https://www.sap.com)",