@sap/cds-compiler 3.9.10 → 3.9.12
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 +15 -0
- package/lib/api/main.js +13 -13
- package/lib/api/options.js +3 -3
- package/lib/base/message-registry.js +4 -3
- package/lib/checks/validator.js +4 -4
- package/lib/compiler/builtins.js +2 -2
- package/lib/edm/annotations/genericTranslation.js +3 -2
- package/lib/edm/annotations/preprocessAnnotations.js +4 -4
- package/lib/edm/csn2edm.js +11 -1
- package/lib/edm/edmUtils.js +1 -1
- package/lib/transform/db/applyTransformations.js +6 -6
- package/lib/transform/db/expansion.js +2 -2
- package/lib/transform/db/flattening.js +1 -1
- package/lib/transform/db/transformExists.js +2 -0
- package/lib/transform/forOdataNew.js +5 -1
- package/lib/transform/translateAssocsToJoins.js +2 -1
- package/lib/transform/universalCsn/universalCsnEnricher.js +4 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,21 @@
|
|
|
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
|
+
|
|
11
|
+
## Version 3.9.12 - 2023-12-06
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- compiler:
|
|
16
|
+
+ SQL function `STDDEV(*)` was not parsable.
|
|
17
|
+
+ Numbers in scientific notation `-1e1` were sometimes not recognized via CSN input.
|
|
18
|
+
- for.odata: Fix crash when using a projection with associations as action parameter type.
|
|
19
|
+
- for.hana: Fix a bug in association to join translation, expect ON condition operand to be a function without arguments.
|
|
20
|
+
- to.edm(x):
|
|
21
|
+
+ Omit `EntitySet` attribute on `Edm.FunctionImport` and `Edm.ActionImport` that return a singleton.
|
|
22
|
+
+ Don't render `Scale: variable` for `cds.Decimal(scale:0)`.
|
|
23
|
+
- to.sql/hdi/hdbcds: consider `having` predicate for `exists` expansion
|
|
24
|
+
|
|
10
25
|
## Version 3.9.10 - 2023-08-25
|
|
11
26
|
|
|
12
27
|
### Fixed
|
package/lib/api/main.js
CHANGED
|
@@ -48,7 +48,7 @@ const warnAboutMismatchOdata = [ 'odataVersion' ];
|
|
|
48
48
|
* @param {string} transformation Name of the transformation - odata or hana
|
|
49
49
|
* @param {NestedOptions} options Options used for the transformation
|
|
50
50
|
* @param {string[]} relevantOptionNames Option names that are defining characteristics
|
|
51
|
-
* @param {string[]} [optionalOptionNames
|
|
51
|
+
* @param {string[]} [optionalOptionNames] Option names that should be attached as a fyi
|
|
52
52
|
*/
|
|
53
53
|
function attachTransformerCharacteristics( csn, transformation, options,
|
|
54
54
|
relevantOptionNames, optionalOptionNames = [] ) {
|
|
@@ -141,7 +141,7 @@ function odataInternal( csn, internalOptions ) {
|
|
|
141
141
|
* Return a odata-transformed CSN
|
|
142
142
|
*
|
|
143
143
|
* @param {CSN.Model} csn Clean input CSN
|
|
144
|
-
* @param {ODataOptions} [options
|
|
144
|
+
* @param {ODataOptions} [options] Options
|
|
145
145
|
* @returns {oDataCSN} Return an oData-pre-processed CSN
|
|
146
146
|
*/
|
|
147
147
|
function odata( csn, options = {} ) {
|
|
@@ -154,7 +154,7 @@ function odata( csn, options = {} ) {
|
|
|
154
154
|
* Process the given csn back to cdl.
|
|
155
155
|
*
|
|
156
156
|
* @param {object} csn CSN to process
|
|
157
|
-
* @param {object} [options
|
|
157
|
+
* @param {object} [options] Options
|
|
158
158
|
* @returns {object} { model: string, namespace: string }
|
|
159
159
|
*/
|
|
160
160
|
function cdl( csn, options = {} ) {
|
|
@@ -167,7 +167,7 @@ function cdl( csn, options = {} ) {
|
|
|
167
167
|
* Transform a CSN like to.sql
|
|
168
168
|
*
|
|
169
169
|
* @param {CSN.Model} csn Plain input CSN
|
|
170
|
-
* @param {SqlOptions} [options
|
|
170
|
+
* @param {SqlOptions} [options] Options
|
|
171
171
|
* @returns {CSN.Model} CSN transformed like to.sql
|
|
172
172
|
* @private
|
|
173
173
|
*/
|
|
@@ -182,7 +182,7 @@ function forSql( csn, options = {} ) {
|
|
|
182
182
|
* Transform a CSN like to.hdi
|
|
183
183
|
*
|
|
184
184
|
* @param {CSN.Model} csn Plain input CSN
|
|
185
|
-
* @param {HdiOptions} [options
|
|
185
|
+
* @param {HdiOptions} [options] Options
|
|
186
186
|
* @returns {CSN.Model} CSN transformed like to.hdi
|
|
187
187
|
* @private
|
|
188
188
|
*/
|
|
@@ -197,7 +197,7 @@ function forHdi( csn, options = {} ) {
|
|
|
197
197
|
* Transform a CSN like to.hdbcds
|
|
198
198
|
*
|
|
199
199
|
* @param {CSN.Model} csn Plain input CSN
|
|
200
|
-
* @param {HdbcdsOptions} [options
|
|
200
|
+
* @param {HdbcdsOptions} [options] Options
|
|
201
201
|
* @returns {CSN.Model} CSN transformed like to.hdbcds
|
|
202
202
|
* @private
|
|
203
203
|
*/
|
|
@@ -214,7 +214,7 @@ function forHdbcds( csn, options = {} ) {
|
|
|
214
214
|
* Process the given CSN into SQL.
|
|
215
215
|
*
|
|
216
216
|
* @param {CSN.Model} csn A clean input CSN
|
|
217
|
-
* @param {SqlOptions} [options
|
|
217
|
+
* @param {SqlOptions} [options] Options
|
|
218
218
|
* @returns {SQL[]} Array of SQL statements, tables first, views second
|
|
219
219
|
*/
|
|
220
220
|
function sql( csn, options = {} ) {
|
|
@@ -235,7 +235,7 @@ function sql( csn, options = {} ) {
|
|
|
235
235
|
* Process the given CSN into HDI artifacts.
|
|
236
236
|
*
|
|
237
237
|
* @param {CSN.Model} csn A clean input CSN
|
|
238
|
-
* @param {HdiOptions} [options
|
|
238
|
+
* @param {HdiOptions} [options] Options
|
|
239
239
|
* @returns {HDIArtifacts} { <filename>:<content>, ...}
|
|
240
240
|
*/
|
|
241
241
|
function hdi( csn, options = {} ) {
|
|
@@ -529,7 +529,7 @@ sql.migration = sqlMigration;
|
|
|
529
529
|
* Process the given CSN into HDBCDS artifacts.
|
|
530
530
|
*
|
|
531
531
|
* @param {any} csn A clean input CSN
|
|
532
|
-
* @param {HdbcdsOptions} [options
|
|
532
|
+
* @param {HdbcdsOptions} [options] Options
|
|
533
533
|
* @returns {HDBCDS} { <filename>:<content>, ...}
|
|
534
534
|
*/
|
|
535
535
|
function hdbcds( csn, options = {} ) {
|
|
@@ -546,7 +546,7 @@ function hdbcds( csn, options = {} ) {
|
|
|
546
546
|
* Generate a edm document for the given service
|
|
547
547
|
*
|
|
548
548
|
* @param {CSN|oDataCSN} csn Clean input CSN or a pre-transformed CSN
|
|
549
|
-
* @param {ODataOptions} [options
|
|
549
|
+
* @param {ODataOptions} [options] Options
|
|
550
550
|
* @returns {edm} The JSON representation of the service
|
|
551
551
|
*/
|
|
552
552
|
function edm( csn, options = {} ) {
|
|
@@ -577,7 +577,7 @@ edm.all = edmall;
|
|
|
577
577
|
* Generate edm documents for all services
|
|
578
578
|
*
|
|
579
579
|
* @param {CSN|oDataCSN} csn Clean input CSN or a pre-transformed CSN
|
|
580
|
-
* @param {ODataOptions} [options
|
|
580
|
+
* @param {ODataOptions} [options] Options
|
|
581
581
|
* @returns {edms} { <service>:<JSON representation>, ...}
|
|
582
582
|
*/
|
|
583
583
|
function edmall( csn, options = {} ) {
|
|
@@ -608,7 +608,7 @@ function edmall( csn, options = {} ) {
|
|
|
608
608
|
* Generate a edmx document for the given service
|
|
609
609
|
*
|
|
610
610
|
* @param {CSN|oDataCSN} csn Clean input CSN or a pre-transformed CSN
|
|
611
|
-
* @param {ODataOptions} [options
|
|
611
|
+
* @param {ODataOptions} [options] Options
|
|
612
612
|
* @returns {edmx} The XML representation of the service
|
|
613
613
|
*/
|
|
614
614
|
function edmx( csn, options = {} ) {
|
|
@@ -640,7 +640,7 @@ edmx.all = edmxall;
|
|
|
640
640
|
* Generate edmx documents for all services
|
|
641
641
|
*
|
|
642
642
|
* @param {CSN|oDataCSN} csn Clean input CSN or a pre-transformed CSN
|
|
643
|
-
* @param {ODataOptions} [options
|
|
643
|
+
* @param {ODataOptions} [options] Options
|
|
644
644
|
* @returns {edmxs} { <service>:<XML representation>, ...}
|
|
645
645
|
*/
|
|
646
646
|
function edmxall( csn, options = {} ) {
|
package/lib/api/options.js
CHANGED
|
@@ -74,9 +74,9 @@ const overallOptions = publicOptionsNewAPI.concat(privateOptions);
|
|
|
74
74
|
* Apply defaults and make sure that the "hard requirements" are met,
|
|
75
75
|
* i.e. src: sql if to.sql() was called.
|
|
76
76
|
*
|
|
77
|
-
* @param {FlatOptions} [input
|
|
78
|
-
* @param {FlatOptions} [defaults
|
|
79
|
-
* @param {FlatOptions} [hardRequire
|
|
77
|
+
* @param {FlatOptions} [input] Input options
|
|
78
|
+
* @param {FlatOptions} [defaults] Default options to apply
|
|
79
|
+
* @param {FlatOptions} [hardRequire] Hard requirements to enforce
|
|
80
80
|
* @param {object} [customValidators] Custom validations to run instead of defaults
|
|
81
81
|
* @param {string[]} [combinationValidators] Option combinations to validate
|
|
82
82
|
* @param {string} moduleName The called module, e.g. 'for.odata', 'to.hdi'. Needed to initialize the message functions
|
|
@@ -792,6 +792,7 @@ const centralMessageTexts = {
|
|
|
792
792
|
incompatible: 'Unexpected EDM Type $(TYPE) for OData $(VERSION)',
|
|
793
793
|
facet: 'Unexpected EDM Type facet $(NAME) of type $(TYPE) for OData $(VERSION)',
|
|
794
794
|
external: 'Referenced type $(TYPE) marked as $(ANNO) can\'t be rendered as $(CODE) in service $(NAME) for OData $(VERSION)',
|
|
795
|
+
scale: 'Expected scale $(NUMBER) to be less than or equal to precision $(RAWVALUE)'
|
|
795
796
|
},
|
|
796
797
|
'odata-spec-violation-property-name': 'Expected element name to be different from declaring $(META)',
|
|
797
798
|
'odata-spec-violation-namespace': {
|
|
@@ -819,7 +820,7 @@ const centralMessageTexts = {
|
|
|
819
820
|
'odata-anno-preproc': {
|
|
820
821
|
'std': 'unused message text',
|
|
821
822
|
'nokey': 'Expected target $(NAME) to have a key element for $(ANNO)',
|
|
822
|
-
'multkeys': 'Expected target $(NAME) to have only one key element',
|
|
823
|
+
'multkeys': 'Expected target $(NAME) to have only one key element for $(ANNO)',
|
|
823
824
|
'vhlnokey': 'Expected value help list entity $(NAME) to have a key element for $(ANNO)',
|
|
824
825
|
'vhlmultkeys': 'Expected value help list entity $(NAME) to have only one key element for $(ANNO)',
|
|
825
826
|
'notforentity': 'Unexpected usage of $(ANNO) for an entity',
|
|
@@ -827,8 +828,8 @@ const centralMessageTexts = {
|
|
|
827
828
|
'noassoc': 'Expected association $(ID) to exist for $(ANNO)',
|
|
828
829
|
'vallistignored': '$(NAME) is ignored for $(ANNO) as $(CODE) is present',
|
|
829
830
|
'notastring': 'Expected value to be a string for $(ANNO)',
|
|
830
|
-
'notexist': '
|
|
831
|
-
'txtarr': '
|
|
831
|
+
'notexist': 'Expected entity $(ID) to exist for $(ANNO)',
|
|
832
|
+
'txtarr': 'Expected $(ANNO) shortcut to have a $(NAME) annotation'
|
|
832
833
|
},
|
|
833
834
|
// -----------------------------------------------------------------------------------
|
|
834
835
|
// GenericTranslation:
|
package/lib/checks/validator.js
CHANGED
|
@@ -127,10 +127,10 @@ const commonQueryValidators = [ validateMixinOnCondition ];
|
|
|
127
127
|
*
|
|
128
128
|
* @param {CSN.Model} csn CSN to check
|
|
129
129
|
* @param {object} that Will be provided to the validators via "this"
|
|
130
|
-
* @param {object[]} [csnValidators
|
|
131
|
-
* @param {Function[]} [memberValidators
|
|
132
|
-
* @param {Function[]} [artifactValidators
|
|
133
|
-
* @param {Function[]} [queryValidators
|
|
130
|
+
* @param {object[]} [csnValidators] Validations on whole CSN using applyTransformations
|
|
131
|
+
* @param {Function[]} [memberValidators] Validations on member-level
|
|
132
|
+
* @param {Function[]} [artifactValidators] Validations on artifact-level
|
|
133
|
+
* @param {Function[]} [queryValidators] Validations on query-level
|
|
134
134
|
* @param {object} iterateOptions can be used to skip certain kinds from being iterated e.g. 'action' and 'function' for hana
|
|
135
135
|
* @returns {Function} Function taking no parameters, that cleans up the attached helpers
|
|
136
136
|
*/
|
package/lib/compiler/builtins.js
CHANGED
|
@@ -119,7 +119,7 @@ const specialFunctions = compileFunctions( {
|
|
|
119
119
|
MAX: 'COUNT',
|
|
120
120
|
SUM: 'COUNT',
|
|
121
121
|
AVG: 'COUNT',
|
|
122
|
-
|
|
122
|
+
STDDEV: 'COUNT',
|
|
123
123
|
VAR: 'COUNT',
|
|
124
124
|
LOCATE_REGEXPR: [
|
|
125
125
|
{
|
|
@@ -216,7 +216,7 @@ const timeRegEx = /^T?(\d{1,2}):(\d{1,2})(?::(\d{1,2}))?(?:Z|[+-]\d{2}(?::\d{2})
|
|
|
216
216
|
// eslint-disable-next-line max-len
|
|
217
217
|
const timestampRegEx = /^(-?\d{4})-(\d{2})-(\d{2})[T ](\d{2}):(\d{2})(?::(\d{2})(\.\d{1,7})?)?(?:Z|[+-]\d{2}(?::\d{2})?)?$/;
|
|
218
218
|
// YYYY - MM - dd T HH : mm : ss . fraction TZD
|
|
219
|
-
const numberRegEx = /^[ \t]*[-+]?(\d+(\.\d*)?|\.\d+)(e[-+]
|
|
219
|
+
const numberRegEx = /^[ \t]*[-+]?(\d+(\.\d*)?|\.\d+)(e[-+]?\d+)?[ \t]*$/i;
|
|
220
220
|
|
|
221
221
|
/**
|
|
222
222
|
* Patterns for literal token tests and creation. The value is a map from the
|
|
@@ -1009,8 +1009,9 @@ function csn2annotationEdm(reqDefs, csnVocabularies, serviceName,
|
|
|
1009
1009
|
else {
|
|
1010
1010
|
// regular record
|
|
1011
1011
|
if (dTypeIsACollection) {
|
|
1012
|
-
message('odata-anno-value', msg.location,
|
|
1013
|
-
|
|
1012
|
+
message('odata-anno-value', msg.location, {
|
|
1013
|
+
anno: msg.anno(), str: 'structured', type: dTypeName, '#': 'incompval',
|
|
1014
|
+
});
|
|
1014
1015
|
}
|
|
1015
1016
|
oTarget.append(generateRecord(cAnnoValue, oTermName, dTypeName, dTypeIsACollection, msg));
|
|
1016
1017
|
}
|
|
@@ -40,11 +40,11 @@ function preprocessAnnotations(csn, serviceName, options) {
|
|
|
40
40
|
const keyNames = Object.keys(target.elements).filter(x => target.elements[x].key && !target.elements[x].target);
|
|
41
41
|
if (keyNames.length === 0) {
|
|
42
42
|
keyNames.push('MISSING');
|
|
43
|
-
message('odata-anno-preproc',
|
|
44
|
-
|
|
43
|
+
message('odata-anno-preproc', assoc.$path, { anno, name: targetName, '#': 'nokey' } );
|
|
44
|
+
}
|
|
45
|
+
else if (keyNames.length > 1) {
|
|
46
|
+
message('odata-anno-preproc', assoc.$path, { anno, name: targetName, '#': 'multkeys' });
|
|
45
47
|
}
|
|
46
|
-
else if (keyNames.length > 1)
|
|
47
|
-
message('odata-anno-preproc', null, { anno, name: targetName, '#': 'multkeys' });
|
|
48
48
|
|
|
49
49
|
return keyNames[0];
|
|
50
50
|
}
|
package/lib/edm/csn2edm.js
CHANGED
|
@@ -745,7 +745,7 @@ function csn2edmAll(_csn, _options, serviceNames=undefined) {
|
|
|
745
745
|
if(rt) // add EntitySet attribute only if return type is a non abstract entity
|
|
746
746
|
{
|
|
747
747
|
const definition = schemaCsn.definitions[rt];
|
|
748
|
-
if(definition && definition.kind === 'entity' && !definition.abstract)
|
|
748
|
+
if (definition && definition.kind === 'entity' && !definition.abstract && !edmUtils.isSingleton(definition))
|
|
749
749
|
{
|
|
750
750
|
actionImport.setEdmAttribute('EntitySet', edmUtils.getBaseName(rt));
|
|
751
751
|
}
|
|
@@ -1104,6 +1104,16 @@ function csn2edmAll(_csn, _options, serviceNames=undefined) {
|
|
|
1104
1104
|
{ type:edmType, name, version: (p.v4 ? '4.0' : '2.0'), '#': 'facet' });
|
|
1105
1105
|
}
|
|
1106
1106
|
});
|
|
1107
|
+
if (edmType === 'Edm.Decimal') {
|
|
1108
|
+
const precision = Number.parseInt(p._edmAttributes.Precision, 10);
|
|
1109
|
+
const scale = Number.parseInt(p._edmAttributes.Scale, 10);
|
|
1110
|
+
if (!Number.isNaN(precision) && !Number.isNaN(scale) && scale > precision) {
|
|
1111
|
+
message('odata-spec-violation-type', pLoc,
|
|
1112
|
+
{
|
|
1113
|
+
type: edmType, number: scale, rawvalue: precision, ersion: (p.v4 ? '4.0' : '2.0'), '#': 'scale',
|
|
1114
|
+
});
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1107
1117
|
}
|
|
1108
1118
|
else {
|
|
1109
1119
|
message('odata-spec-violation-type-unknown', pLoc,
|
package/lib/edm/edmUtils.js
CHANGED
|
@@ -610,7 +610,7 @@ function addTypeFacets(node, csn)
|
|
|
610
610
|
// map both floating and variable to => variable
|
|
611
611
|
if(node._edmAttributes.Scale === 'floating')
|
|
612
612
|
node.setEdmAttribute('Scale', 'variable');
|
|
613
|
-
if(
|
|
613
|
+
if (csn.precision == null && csn.scale == null)
|
|
614
614
|
// if Decimal has no p, s set scale 'variable'
|
|
615
615
|
node.setXml( { Scale: 'variable' } ); // floating is V4.01
|
|
616
616
|
}
|
|
@@ -17,8 +17,8 @@ const { setProp } = require('../../base/model');
|
|
|
17
17
|
* @param {object} parent The "parent" of which we transform a property of
|
|
18
18
|
* @param {string} prop The property of parent to start at
|
|
19
19
|
* @param {object} customTransformers Map of prop to transform and function to apply
|
|
20
|
-
* @param {Function[]} [artifactTransformers
|
|
21
|
-
* @param {applyTransformationsOptions} [options
|
|
20
|
+
* @param {Function[]} [artifactTransformers] Transformations to run on the artifacts, like forEachDefinition
|
|
21
|
+
* @param {applyTransformationsOptions} [options]
|
|
22
22
|
* @param {CSN.Path} path Path to parent
|
|
23
23
|
* @returns {object} parent with transformations applied
|
|
24
24
|
*/
|
|
@@ -165,8 +165,8 @@ function applyTransformationsInternal( parent, prop, customTransformers, artifac
|
|
|
165
165
|
*
|
|
166
166
|
* @param {object} csn CSN to enrich in-place
|
|
167
167
|
* @param {object} customTransformers Map of _prop to transform and function to apply
|
|
168
|
-
* @param {Function[]} [artifactTransformers
|
|
169
|
-
* @param {applyTransformationsOptions} [options
|
|
168
|
+
* @param {Function[]} [artifactTransformers] Transformations to run on the artifacts, like forEachDefinition
|
|
169
|
+
* @param {applyTransformationsOptions} [options]
|
|
170
170
|
* @returns {object} CSN with transformations applied
|
|
171
171
|
*/
|
|
172
172
|
function applyTransformations( csn, customTransformers = {}, artifactTransformers = [], options = { } ) {
|
|
@@ -192,7 +192,7 @@ function applyTransformations( csn, customTransformers = {}, artifactTransformer
|
|
|
192
192
|
* @param {object} parent The "parent" of which we transform a property of
|
|
193
193
|
* @param {string} prop The property of parent to start at
|
|
194
194
|
* @param {object} customTransformers Map of prop to transform and function to apply
|
|
195
|
-
* @param {applyTransformationsOptions} [options
|
|
195
|
+
* @param {applyTransformationsOptions} [options]
|
|
196
196
|
* @param {CSN.Path} path Path pointing to parent
|
|
197
197
|
* @returns {object} parent[prop] with transformations applied
|
|
198
198
|
*/
|
|
@@ -213,7 +213,7 @@ function applyTransformationsOnNonDictionary( parent, prop, customTransformers =
|
|
|
213
213
|
*
|
|
214
214
|
* @param {object} dictionary Dictionary to enrich in-place
|
|
215
215
|
* @param {object} customTransformers Map of prop to transform and function to apply
|
|
216
|
-
* @param {applyTransformationsOptions} [options
|
|
216
|
+
* @param {applyTransformationsOptions} [options]
|
|
217
217
|
* @param {CSN.Path} path Path pointing to parent
|
|
218
218
|
* @returns {object} dictionary with transformations applied
|
|
219
219
|
*/
|
|
@@ -516,7 +516,7 @@ function expandStructureReferences( csn, options, pathDelimiter, messageFunction
|
|
|
516
516
|
*
|
|
517
517
|
* @param {Array} thing
|
|
518
518
|
* @param {CSN.Path} path
|
|
519
|
-
* @param {boolean} [withAlias
|
|
519
|
+
* @param {boolean} [withAlias] Whether to "expand" the (implicit) alias aswell.
|
|
520
520
|
* @returns {Array} New array - with all structured things expanded
|
|
521
521
|
*/
|
|
522
522
|
function expand( thing, path, withAlias = false ) {
|
|
@@ -617,7 +617,7 @@ function expandStructureReferences( csn, options, pathDelimiter, messageFunction
|
|
|
617
617
|
*
|
|
618
618
|
* @param {object} base The raw set of things a * can expand to
|
|
619
619
|
* @param {Array} subs Things - the .expand/.inline or .columns
|
|
620
|
-
* @param {string[]} [excluding
|
|
620
|
+
* @param {string[]} [excluding]
|
|
621
621
|
* @returns {Array} If there was a star, expand it and handle shadowing/excluding, else just return subs
|
|
622
622
|
*/
|
|
623
623
|
function replaceStar( base, subs, excluding = [] ) {
|
|
@@ -192,7 +192,7 @@ function flattenAllStructStepsInRefs( csn, options, resolved, pathDelimiter, ite
|
|
|
192
192
|
* For each step of the links, check if there is a type reference.
|
|
193
193
|
* If there is, resolve it and store the result in a WeakMap.
|
|
194
194
|
*
|
|
195
|
-
* @param {Array} [links
|
|
195
|
+
* @param {Array} [links]
|
|
196
196
|
* @todo seems too hacky
|
|
197
197
|
* @returns {WeakMap} A WeakMap where a link is the key and the type is the value
|
|
198
198
|
*/
|
|
@@ -63,6 +63,8 @@ function handleExists( csn, options, error, inspectRef, initDefinition, dropDefi
|
|
|
63
63
|
if (query.SELECT && query.SELECT.where && query.SELECT.where.length > 1)
|
|
64
64
|
toProcess.push([ path.slice(0, -1), path.concat('where') ]);
|
|
65
65
|
|
|
66
|
+
if (query.SELECT && query.SELECT.having?.length > 1)
|
|
67
|
+
toProcess.push([ path.slice(0, -1), path.concat('having') ]);
|
|
66
68
|
|
|
67
69
|
if (query.SELECT && query.SELECT.columns)
|
|
68
70
|
toProcess.push([ path.slice(0, -1), path.concat('columns') ]);
|
|
@@ -98,7 +98,9 @@ function transform4odataWithCsn(inputModel, options) {
|
|
|
98
98
|
inspectRef,
|
|
99
99
|
artifactRef,
|
|
100
100
|
effectiveType,
|
|
101
|
-
getFinalTypeInfo
|
|
101
|
+
getFinalTypeInfo,
|
|
102
|
+
dropDefinitionCache,
|
|
103
|
+
initDefinition,
|
|
102
104
|
} = csnUtils;
|
|
103
105
|
|
|
104
106
|
// are we working with structured OData or not
|
|
@@ -147,6 +149,8 @@ function transform4odataWithCsn(inputModel, options) {
|
|
|
147
149
|
// TODO: handle artifact.projection instead of artifact.query correctly in future V2
|
|
148
150
|
if (def.kind === 'entity' && def.projection) {
|
|
149
151
|
def.query = { SELECT: def.projection };
|
|
152
|
+
dropDefinitionCache(def);
|
|
153
|
+
initDefinition(def);
|
|
150
154
|
}
|
|
151
155
|
}],
|
|
152
156
|
{ skipArtifact: isExternalServiceMember }
|
|
@@ -730,7 +730,8 @@ function translateAssocsToJoins(model, inputOptions = {})
|
|
|
730
730
|
// this will substitute multiple backlink conditions ($self = ... AND $self = ...AND ...)
|
|
731
731
|
if(expr.op) {
|
|
732
732
|
let x = clone(expr);
|
|
733
|
-
|
|
733
|
+
if(expr.args)
|
|
734
|
+
x.args = expr.args.map(cloneOnCondition);
|
|
734
735
|
return x;
|
|
735
736
|
}
|
|
736
737
|
|
|
@@ -328,9 +328,9 @@ module.exports = (csn, options) => {
|
|
|
328
328
|
* passed to this function.
|
|
329
329
|
*
|
|
330
330
|
* @param {CSN.Element} member
|
|
331
|
-
* @param {object} [except
|
|
331
|
+
* @param {object} [except] List of properties which should not be propagated along the origin chain
|
|
332
332
|
* of the `member`
|
|
333
|
-
* @param {object} [force
|
|
333
|
+
* @param {object} [force] Overwrite any member propagation rules or any except and always propagate the corresponding keys
|
|
334
334
|
*/
|
|
335
335
|
function propagateMemberPropsFromOrigin( member, except = null, force = null ) {
|
|
336
336
|
const memberChain = getOriginChain(member);
|
|
@@ -613,8 +613,8 @@ module.exports = (csn, options) => {
|
|
|
613
613
|
* @param {object} to
|
|
614
614
|
* @param {Function} getCustomRule getter for the `memberProps` or `defProps`
|
|
615
615
|
* which shall be used for retrieving custom rules
|
|
616
|
-
* @param {object} [except
|
|
617
|
-
* @param {object} [force
|
|
616
|
+
* @param {object} [except] array of properties which should not be propagated
|
|
617
|
+
* @param {object} [force] Force propagation of the contained keys via a custom rule.
|
|
618
618
|
*/
|
|
619
619
|
function copyProperties( from, to, getCustomRule, except = null, force = null ) {
|
|
620
620
|
const keys = Object.keys(from);
|