@sap/cds-compiler 6.7.2 → 6.8.0
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 +34 -0
- package/bin/cdsc.js +5 -5
- package/bin/cdsse.js +1 -1
- package/lib/api/main.js +9 -8
- package/lib/api/options.js +2 -1
- package/lib/api/validate.js +1 -1
- package/lib/base/error.js +2 -0
- package/lib/base/message-registry.js +7 -2
- package/lib/base/messages.js +2 -2
- package/lib/{optionProcessor.js → base/optionProcessor.js} +3 -3
- package/lib/base/{model.js → specialOptions.js} +16 -39
- package/lib/checks/arrayOfs.js +1 -1
- package/lib/checks/elements.js +1 -1
- package/lib/checks/enricher.js +2 -2
- package/lib/checks/featureFlags.js +54 -24
- package/lib/checks/foreignKeys.js +1 -1
- package/lib/checks/invalidTarget.js +1 -1
- package/lib/checks/managedInType.js +1 -1
- package/lib/checks/onConditions.js +1 -1
- package/lib/checks/queryNoDbArtifacts.js +1 -1
- package/lib/checks/validator.js +10 -14
- package/lib/compiler/builtins.js +1 -1
- package/lib/compiler/checks.js +3 -3
- package/lib/compiler/define.js +5 -2
- package/lib/{base → compiler}/dictionaries.js +2 -0
- package/lib/compiler/extend.js +2 -2
- package/lib/compiler/generate.js +2 -2
- package/lib/compiler/index.js +11 -3
- package/lib/compiler/kick-start.js +1 -1
- package/lib/compiler/populate.js +2 -2
- package/lib/compiler/resolve.js +4 -2
- package/lib/compiler/shared.js +35 -6
- package/lib/compiler/utils.js +2 -4
- package/lib/compiler/xpr-rewrite.js +1 -1
- package/lib/edm/annotations/edmJson.js +2 -4
- package/lib/edm/annotations/genericTranslation.js +2 -1
- package/lib/edm/csn2edm.js +3 -2
- package/lib/edm/edmAnnoPreprocessor.js +1 -1
- package/lib/edm/edmInboundChecks.js +2 -1
- package/lib/edm/edmPreprocessor.js +3 -3
- package/lib/edm/edmUtils.js +2 -2
- package/lib/gen/BaseParser.js +1 -12
- package/lib/gen/CdlGrammar.checksum +1 -1
- package/lib/gen/CdlParser.js +1068 -1067
- package/lib/json/from-csn.js +7 -2
- package/lib/json/to-csn.js +17 -2
- package/lib/main.js +3 -3
- package/lib/model/csnUtils.js +2 -2
- package/lib/modelCompare/compare.js +1 -1
- package/lib/modelCompare/utils/filter.js +1 -0
- package/lib/parsers/AstBuildingParser.js +40 -3
- package/lib/parsers/index.js +1 -1
- package/lib/render/manageConstraints.js +1 -1
- package/lib/render/toCdl.js +3 -3
- package/lib/render/toHdbcds.js +2 -2
- package/lib/render/toSql.js +7 -7
- package/lib/render/utils/common.js +9 -2
- package/lib/render/utils/sql.js +14 -5
- package/lib/render/utils/standardDatabaseFunctions.js +108 -99
- package/lib/sql-identifier.js +9 -1
- package/lib/{model → tool-lib}/enrichCsn.js +2 -2
- package/lib/{model → tool-lib}/revealInternalProperties.js +2 -1
- package/lib/transform/addTenantFields.js +1 -1
- package/lib/transform/db/applyTransformations.js +1 -1
- package/lib/transform/db/assertUnique.js +1 -1
- package/lib/transform/db/assocsToQueries/transformExists.js +1 -1
- package/lib/transform/db/backlinks.js +2 -2
- package/lib/transform/db/expansion.js +2 -2
- package/lib/transform/db/flattening.js +3 -4
- package/lib/transform/db/killAnnotations.js +1 -0
- package/lib/transform/db/processSqlServices.js +2 -1
- package/lib/transform/db/rewriteCalculatedElements.js +2 -2
- package/lib/transform/db/temporal.js +30 -5
- package/lib/transform/db/views.js +16 -20
- package/lib/transform/draft/db.js +1 -2
- package/lib/transform/effective/associations.js +1 -1
- package/lib/transform/effective/flattening.js +1 -1
- package/lib/transform/effective/main.js +19 -4
- package/lib/transform/effective/types.js +1 -1
- package/lib/transform/{odata/fioriTreeViews.js → fioriTreeViews.js} +48 -25
- package/lib/transform/forOdata.js +5 -5
- package/lib/transform/forRelationalDB.js +41 -9
- package/lib/transform/localized.js +2 -2
- package/lib/transform/odata/createForeignKeys.js +1 -1
- package/lib/transform/odata/flattening.js +2 -2
- package/lib/transform/odata/toFinalBaseType.js +3 -2
- package/lib/transform/odata/typesExposure.js +3 -2
- package/lib/transform/transformUtils.js +2 -2
- package/lib/transform/translateAssocsToJoins.js +30 -29
- package/lib/transform/tupleExpansion.js +4 -4
- package/lib/transform/universalCsn/universalCsnEnricher.js +7 -3
- package/lib/transform/universalCsn/utils.js +1 -1
- package/lib/{base → utils}/lazyload.js +9 -0
- package/lib/{base → utils}/node-helpers.js +2 -0
- package/lib/utils/objectUtils.js +29 -6
- package/lib/{base → utils}/optionProcessorHelper.js +16 -6
- package/package.json +2 -2
- /package/lib/{model → base}/cloneCsn.js +0 -0
- /package/lib/{model → base}/csnRefs.js +0 -0
- /package/lib/{model/api.js → base/model-api.js} +0 -0
- /package/lib/{api → base}/trace.js +0 -0
- /package/lib/{model → base}/xprAsTree.js +0 -0
- /package/lib/{inspect → tool-lib}/index.js +0 -0
- /package/lib/{inspect → tool-lib}/inspectModelStatistics.js +0 -0
- /package/lib/{inspect → tool-lib}/inspectPropagation.js +0 -0
- /package/lib/{inspect → tool-lib}/inspectUtils.js +0 -0
- /package/lib/{base → utils}/shuffle.js +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -13,6 +13,40 @@ we might not list every change in its behavior here.
|
|
|
13
13
|
Productive code should never require a `beta` flag to be set, and
|
|
14
14
|
might use a deprecated flag only for a limited period of time.
|
|
15
15
|
|
|
16
|
+
## Version 6.8.0 - 2026-03-05
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
- **api:** basic experimental support for code completion in `cds repl`
|
|
21
|
+
- **compiler:**
|
|
22
|
+
+ retain original meta property in CSN
|
|
23
|
+
+ add compilerCsnFlavor to meta property
|
|
24
|
+
- **sql:**
|
|
25
|
+
+ Add support for `cds.Vector`
|
|
26
|
+
+ Allow migration from cds.String to cds.LargeString
|
|
27
|
+
+ Fiori Tree Views in the database backend
|
|
28
|
+
+ For postgres: warning for identifiers that exceed the databases length limit
|
|
29
|
+
|
|
30
|
+
### Bug Fixes
|
|
31
|
+
|
|
32
|
+
- **sql:**
|
|
33
|
+
+ do not report validation errors on entities marked as `@cds.persistence.skip`
|
|
34
|
+
+ normalize named arguments for portable functions
|
|
35
|
+
+ properly flatten associations for temporal unique constraints
|
|
36
|
+
|
|
37
|
+
### Improvements
|
|
38
|
+
|
|
39
|
+
- **compiler:**
|
|
40
|
+
+ improve warning in case of invalid type for key
|
|
41
|
+
+ simplify syntax error text when expecting Comparison and Operator tokens
|
|
42
|
+
+ improve support for code completion with `case` expressions, queries, and subqueries
|
|
43
|
+
|
|
44
|
+
## Version 6.7.3 - 2026-02-11
|
|
45
|
+
|
|
46
|
+
### Fixed
|
|
47
|
+
|
|
48
|
+
- **sql:** do not resolve path navigations to virtual elements which resulted in an internal error.
|
|
49
|
+
|
|
16
50
|
## Version 6.7.2 - 2026-02-04
|
|
17
51
|
|
|
18
52
|
### Fixed
|
package/bin/cdsc.js
CHANGED
|
@@ -25,9 +25,9 @@ const { toRename: _toRename } = require('../lib/render/toRename');
|
|
|
25
25
|
const util = require('util');
|
|
26
26
|
const fs = require('fs');
|
|
27
27
|
const path = require('path');
|
|
28
|
-
const { reveal } = require('../lib/
|
|
29
|
-
const enrichCsn = require('../lib/
|
|
30
|
-
const { optionProcessor } = require('../lib/optionProcessor');
|
|
28
|
+
const { reveal } = require('../lib/tool-lib/revealInternalProperties');
|
|
29
|
+
const enrichCsn = require('../lib/tool-lib/enrichCsn');
|
|
30
|
+
const { optionProcessor } = require('../lib/base/optionProcessor');
|
|
31
31
|
const {
|
|
32
32
|
explainMessage, hasMessageExplanation, sortMessages,
|
|
33
33
|
messageIdsWithExplanation, makeMessageFunction,
|
|
@@ -35,7 +35,7 @@ const {
|
|
|
35
35
|
const { term } = require('../lib/utils/term');
|
|
36
36
|
const { addLocalizationViews } = require('../lib/transform/localized');
|
|
37
37
|
const { addTenantFields } = require('../lib/transform/addTenantFields');
|
|
38
|
-
const { availableBetaFlags } = require('../lib/base/
|
|
38
|
+
const { availableBetaFlags } = require('../lib/base/specialOptions');
|
|
39
39
|
const { alterConstraintsWithCsn } = require('../lib/render/manageConstraints');
|
|
40
40
|
const { tmpFilePath, readStream } = require('../lib/utils/file');
|
|
41
41
|
|
|
@@ -548,7 +548,7 @@ async function executeCommandLine( command, options, args ) {
|
|
|
548
548
|
}
|
|
549
549
|
|
|
550
550
|
function inspect( model ) {
|
|
551
|
-
const inspectModel = require('../lib/
|
|
551
|
+
const inspectModel = require('../lib/tool-lib');
|
|
552
552
|
|
|
553
553
|
if (options.statistics) {
|
|
554
554
|
const result = inspectModel.inspectModelStatistics(model, options);
|
package/bin/cdsse.js
CHANGED
|
@@ -25,7 +25,7 @@ const path = require('path');
|
|
|
25
25
|
const compiler = require('../lib/compiler');
|
|
26
26
|
const main = require('../lib/main');
|
|
27
27
|
const { locationString } = require('../lib/base/messages');
|
|
28
|
-
const { availableBetaFlags: beta } = require('../lib/base/
|
|
28
|
+
const { availableBetaFlags: beta } = require('../lib/base/specialOptions');
|
|
29
29
|
|
|
30
30
|
const { argv } = process;
|
|
31
31
|
const cmd = commands[argv[2]];
|
package/lib/api/main.js
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
5
|
-
const lazyload = require('../
|
|
5
|
+
const lazyload = require('../utils/lazyload')( module );
|
|
6
6
|
|
|
7
7
|
const prepareOptions = lazyload('./options');
|
|
8
|
-
const
|
|
8
|
+
const specialOptions = lazyload('../base/specialOptions');
|
|
9
9
|
const location = lazyload('../base/location');
|
|
10
10
|
const messages = lazyload('../base/messages');
|
|
11
11
|
const compiler = lazyload('../compiler/index');
|
|
@@ -27,8 +27,8 @@ const effective = lazyload('../transform/effective/main');
|
|
|
27
27
|
const toHdbcds = lazyload('../render/toHdbcds');
|
|
28
28
|
const baseError = lazyload('../base/error');
|
|
29
29
|
const csnToEdm = lazyload('../edm/csn2edm');
|
|
30
|
-
const trace = lazyload('
|
|
31
|
-
const cloneCsn = lazyload('../
|
|
30
|
+
const trace = lazyload('../base/trace');
|
|
31
|
+
const cloneCsn = lazyload('../base/cloneCsn');
|
|
32
32
|
const objectUtils = lazyload('../utils/objectUtils');
|
|
33
33
|
|
|
34
34
|
/**
|
|
@@ -56,6 +56,7 @@ const warnAboutMismatchOdata = [ 'odataVersion' ];
|
|
|
56
56
|
* @param {string[]} relevantOptionNames Option names that are defining characteristics
|
|
57
57
|
* @param {string[]} [optionalOptionNames] Option names that should be attached as a fyi
|
|
58
58
|
*/
|
|
59
|
+
// TODO: move this function to some other place
|
|
59
60
|
function attachTransformerCharacteristics( csn, transformation, options,
|
|
60
61
|
relevantOptionNames, optionalOptionNames = [] ) {
|
|
61
62
|
const relevant = {};
|
|
@@ -75,10 +76,10 @@ function attachTransformerCharacteristics( csn, transformation, options,
|
|
|
75
76
|
relevant[name] = options[name];
|
|
76
77
|
}
|
|
77
78
|
if (!csn.meta)
|
|
78
|
-
|
|
79
|
+
objectUtils.setProp(csn, 'meta', {});
|
|
79
80
|
|
|
80
|
-
|
|
81
|
-
|
|
81
|
+
objectUtils.setProp(csn.meta, 'options', relevant);
|
|
82
|
+
objectUtils.setProp(csn.meta, 'transformation', transformation);
|
|
82
83
|
}
|
|
83
84
|
|
|
84
85
|
/**
|
|
@@ -1166,7 +1167,7 @@ function publishCsnProcessor( processor, _name ) {
|
|
|
1166
1167
|
try {
|
|
1167
1168
|
const messageFunctions = messages.makeMessageFunction(csn, options, _name);
|
|
1168
1169
|
if (options.deprecated)
|
|
1169
|
-
|
|
1170
|
+
specialOptions.checkRemovedDeprecatedFlags( options, messageFunctions );
|
|
1170
1171
|
|
|
1171
1172
|
checkOutdatedOptions( options, messageFunctions );
|
|
1172
1173
|
csn = ensureClientCsn( csn, options, messageFunctions, _name );
|
package/lib/api/options.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
// The options are specified in ../optionProcessor.js (and some other files).
|
|
3
|
+
// The options are specified in ../base/optionProcessor.js (and some other files).
|
|
4
4
|
// Some backends feel the need to "translate" option, which require to list
|
|
5
5
|
// all options also here (as “public" or "private" option).
|
|
6
6
|
|
|
@@ -36,6 +36,7 @@ const publicOptionsNewAPI = [
|
|
|
36
36
|
'pre2134ReferentialConstraintNames',
|
|
37
37
|
'betterSqliteSessionVariables',
|
|
38
38
|
'fewerLocalizedViews',
|
|
39
|
+
'sqliteRealAffinityForDecimal',
|
|
39
40
|
'withHanaAssociations',
|
|
40
41
|
'standardDatabaseFunctions',
|
|
41
42
|
'booleanEquality',
|
package/lib/api/validate.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
// The options are specified in ../optionProcessor.js (and some other files).
|
|
3
|
+
// The options are specified in ../base/optionProcessor.js (and some other files).
|
|
4
4
|
// Options with non-boolean values must also be listed in this file.
|
|
5
5
|
|
|
6
6
|
const { forEach } = require('../utils/objectUtils');
|
package/lib/base/error.js
CHANGED
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
'use strict';
|
|
37
37
|
|
|
38
38
|
const { CompilerAssertion } = require( './error' );
|
|
39
|
-
const { isDeprecatedEnabled } = require( './
|
|
39
|
+
const { isDeprecatedEnabled } = require( './specialOptions' );
|
|
40
40
|
|
|
41
41
|
const configurableForValidValues = {
|
|
42
42
|
__proto__: null,
|
|
@@ -135,6 +135,7 @@ const centralMessages = {
|
|
|
135
135
|
'type-ignoring-argument': { severity: 'Error', configurableFor: true },
|
|
136
136
|
'type-expected-builtin': { severity: 'Error', configurableFor: true },
|
|
137
137
|
'type-expecting-service-target': { severity: 'Error', configurableFor: true },
|
|
138
|
+
'type-invalid-for-key': { severity: 'Warning' },
|
|
138
139
|
'ref-expecting-const': { severity: 'Error' },
|
|
139
140
|
'ref-expecting-foreign-key': { severity: 'Error' },
|
|
140
141
|
'ref-invalid-source': { severity: 'Error' },
|
|
@@ -154,6 +155,7 @@ const centralMessages = {
|
|
|
154
155
|
'query-unexpected-structure-hdbcds': { severity: 'Error' },
|
|
155
156
|
'query-ignoring-param-nullability': { severity: 'Info' },
|
|
156
157
|
'query-expected-identifier': { severity: 'Error' },
|
|
158
|
+
'query-invalid-identifier': { severity: 'Warning' },
|
|
157
159
|
|
|
158
160
|
'recalculated-localized': { severity: 'Info' }, // KEEP: Downgrade in lib/transform/translateAssocsToJoins.js
|
|
159
161
|
'redirected-implicitly-ambiguous': { severity: 'Error', configurableFor: true }, // does not hurt us - TODO: ref-ambiguous-target
|
|
@@ -728,6 +730,7 @@ const centralMessageTexts = {
|
|
|
728
730
|
'ref-undefined-def': {
|
|
729
731
|
std: 'Artifact $(ART) has not been found',
|
|
730
732
|
// TODO: proposal 'No definition of $(NAME) found',
|
|
733
|
+
hint: 'Artifact $(ART) has not been found. Did you mean to write $(CODE)?',
|
|
731
734
|
element: 'Artifact $(ART) has no element $(MEMBER)',
|
|
732
735
|
},
|
|
733
736
|
'ref-undefined-param': 'Entity $(ART) has no parameter $(ID)',
|
|
@@ -866,6 +869,7 @@ const centralMessageTexts = {
|
|
|
866
869
|
std: 'Unexpected arguments in path $(ELEMREF)', // unused
|
|
867
870
|
'on-condition': 'ON-conditions must not contain parameters, step $(ID) of path $(ELEMREF)',
|
|
868
871
|
calc: 'Unexpected arguments in path $(ELEMREF) of stored calculated element; only simple paths can be used here',
|
|
872
|
+
vector_length: 'Unexpected length of vector $(ELEMREF). The length must be divisble by 4',
|
|
869
873
|
},
|
|
870
874
|
'ref-unsupported-type': {
|
|
871
875
|
std: 'Type $(TYPE) is not supported',
|
|
@@ -955,6 +959,7 @@ const centralMessageTexts = {
|
|
|
955
959
|
missing: 'Expecting service entity $(TARGET); it does not have the key element $(ID) of the provided model target',
|
|
956
960
|
order: 'Expecting service entity $(TARGET); its key elements are in a different order than those of the provided model target',
|
|
957
961
|
},
|
|
962
|
+
'type-invalid-for-key': 'Type $(TYPE) is not supported for key elements',
|
|
958
963
|
|
|
959
964
|
'anno-builtin': 'Builtin types should not be annotated nor extended. Use custom type instead',
|
|
960
965
|
'ext-undefined-def': 'Artifact $(ART) has not been found',
|
|
@@ -1025,7 +1030,6 @@ const centralMessageTexts = {
|
|
|
1025
1030
|
std: '$(KEYWORD) is not supported here', // unused variant
|
|
1026
1031
|
kind: '$(KEYWORD) is only supported for elements in an entity or an aspect',
|
|
1027
1032
|
sub: '$(KEYWORD) is only supported for top-level elements',
|
|
1028
|
-
type: '$(KEYWORD) is not supported for elements of type $(TYPE)',
|
|
1029
1033
|
},
|
|
1030
1034
|
'def-unexpected-localized': {
|
|
1031
1035
|
std: 'Unexpected $(KEYWORD)',
|
|
@@ -1199,6 +1203,7 @@ const centralMessageTexts = {
|
|
|
1199
1203
|
std: 'Expected identifier for select item',
|
|
1200
1204
|
assoc: 'Expected identifier as the association\'s name',
|
|
1201
1205
|
},
|
|
1206
|
+
'query-invalid-identifier': 'Expected identifier for SQL dialect $(NAME) to not exceed $(NUMBER) characters',
|
|
1202
1207
|
'query-unsupported-calc': {
|
|
1203
1208
|
std: 'Using nested projections next to calculated elements is not supported, yet',
|
|
1204
1209
|
inside: 'Using calculated elements in nested projections is not supported, yet',
|
package/lib/base/messages.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
const { term } = require('../utils/term');
|
|
8
8
|
const { Location, locationString } = require('./location');
|
|
9
|
-
const { isBetaEnabled } = require('./
|
|
9
|
+
const { isBetaEnabled } = require('./specialOptions');
|
|
10
10
|
const {
|
|
11
11
|
centralMessages,
|
|
12
12
|
configurableForValidValues,
|
|
@@ -14,7 +14,7 @@ const {
|
|
|
14
14
|
oldMessageIds,
|
|
15
15
|
} = require('./message-registry');
|
|
16
16
|
const _messageIdsWithExplanation = require('../../share/messages/message-explanations.json').messages;
|
|
17
|
-
const { analyseCsnPath, traverseQuery } = require('../
|
|
17
|
+
const { analyseCsnPath, traverseQuery } = require('../base/csnRefs');
|
|
18
18
|
const { CompilerAssertion } = require('./error');
|
|
19
19
|
const { getArtifactName } = require('../compiler/base');
|
|
20
20
|
const { cdlNewLineRegEx } = require('../language/textUtils');
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
// - Also list the option in the `help` text, used with `cdsc -h`.
|
|
9
9
|
// - All options must also be added to ./api/options.js.
|
|
10
10
|
// - Specify valid values for non-boolean options in ./api/validate.js.
|
|
11
|
-
// - Beta and deprecated options are specified in ./base/
|
|
11
|
+
// - Beta and deprecated options are specified in ./base/specialOptions.js.
|
|
12
12
|
|
|
13
13
|
'use strict';
|
|
14
14
|
|
|
15
|
-
const { createOptionProcessor } = require('
|
|
16
|
-
const { availableBetaFlags } = require('./
|
|
15
|
+
const { createOptionProcessor } = require('../utils/optionProcessorHelper');
|
|
16
|
+
const { availableBetaFlags } = require('./specialOptions');
|
|
17
17
|
|
|
18
18
|
// This option processor is used both by the command line parser (to translate cmd line options
|
|
19
19
|
// into an options object) and by the API functions (to verify options)
|
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Definitions for beta and deprecated options
|
|
2
2
|
|
|
3
|
-
//
|
|
4
|
-
//
|
|
3
|
+
// Normal options are in ../model/optionProcessor.js (and some other files),
|
|
4
|
+
// unfortunately partly non-grep-able (option `fooBar` is defined via `--foo-bar`)
|
|
5
5
|
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
|
-
const { forEach } = require('../utils/objectUtils');
|
|
9
|
-
|
|
10
|
-
// Normal options are in ../optionProcessor.js (and some other files),
|
|
11
|
-
// unfortunately partly non-grep-able (option `fooBar` is defined via `--foo-bar`)
|
|
12
|
-
|
|
13
8
|
/**
|
|
14
9
|
* Object of all available beta flags that will be enabled/disabled by `--beta-mode`
|
|
15
10
|
* through cdsc. Only intended for INTERNAL USE.
|
|
@@ -47,12 +42,12 @@ const availableDeprecatedFlags = {
|
|
|
47
42
|
ignoreSpecifiedQueryElements: true,
|
|
48
43
|
};
|
|
49
44
|
|
|
50
|
-
// Deprecated flags that were removed in
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
45
|
+
// Deprecated flags that were removed in newer version and are complained about.
|
|
46
|
+
const oldDeprecatedFlags = {
|
|
47
|
+
includesNonShadowedFirst: true,
|
|
48
|
+
eagerPersistenceForGeneratedEntities: true,
|
|
49
|
+
noKeyPropagationWithExpansions: true,
|
|
50
|
+
};
|
|
56
51
|
|
|
57
52
|
/**
|
|
58
53
|
* Test for early-adaptor feature, stored in option `beta`(new-style) / `betaMode`(old-style)
|
|
@@ -98,48 +93,30 @@ function isDeprecatedEnabled( options, feature = null ) {
|
|
|
98
93
|
}
|
|
99
94
|
|
|
100
95
|
/**
|
|
101
|
-
* In cds-compiler
|
|
96
|
+
* In the current cds-compiler, we might have removed old deprecated flags. That can lead to silent
|
|
102
97
|
* errors such as entity/view names changing. To ensure that the user is forced
|
|
103
98
|
* to change their code, emit an error if one of such removed flags was used.
|
|
104
99
|
*
|
|
105
100
|
* @param {CSN.Options} options
|
|
106
101
|
* @param error Error message function returned by makeMessageFunction().
|
|
107
102
|
*/
|
|
108
|
-
function checkRemovedDeprecatedFlags(
|
|
103
|
+
function checkRemovedDeprecatedFlags( { deprecated, messages }, { error } ) {
|
|
109
104
|
// Assume that we emitted these errors once if a message with this ID was found.
|
|
110
|
-
if (!
|
|
105
|
+
if (!deprecated || messages?.some( m => m.messageId === 'api-invalid-deprecated' ))
|
|
111
106
|
return;
|
|
112
107
|
|
|
113
|
-
|
|
114
|
-
if (
|
|
115
|
-
error('api-invalid-deprecated', null, { name: key },
|
|
116
|
-
|
|
108
|
+
Object.keys( deprecated ).forEach( ( key ) => {
|
|
109
|
+
if (deprecated[key] && oldDeprecatedFlags[key]) { // why testing the value of the option?
|
|
110
|
+
error( 'api-invalid-deprecated', null, { name: key },
|
|
111
|
+
'Deprecated flag $(NAME) has been removed in CDS compiler v6' );
|
|
117
112
|
}
|
|
118
113
|
});
|
|
119
114
|
}
|
|
120
115
|
|
|
121
|
-
/**
|
|
122
|
-
* Like `obj.prop = value`, but not contained in JSON / CSN
|
|
123
|
-
* It's important to set enumerable explicitly to false (although 'false' is the default),
|
|
124
|
-
* as else, if the property already exists, it keeps the old setting for enumerable.
|
|
125
|
-
*
|
|
126
|
-
* @param {object} obj
|
|
127
|
-
* @param {string} prop
|
|
128
|
-
* @param {any} value
|
|
129
|
-
*/
|
|
130
|
-
function setProp( obj, prop, value ) {
|
|
131
|
-
const descriptor = {
|
|
132
|
-
value, configurable: true, writable: true, enumerable: false,
|
|
133
|
-
};
|
|
134
|
-
Object.defineProperty( obj, prop, descriptor );
|
|
135
|
-
return value;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
116
|
|
|
139
117
|
module.exports = {
|
|
140
118
|
isBetaEnabled,
|
|
141
119
|
availableBetaFlags,
|
|
142
120
|
isDeprecatedEnabled,
|
|
143
121
|
checkRemovedDeprecatedFlags,
|
|
144
|
-
setProp,
|
|
145
122
|
};
|
package/lib/checks/arrayOfs.js
CHANGED
package/lib/checks/elements.js
CHANGED
|
@@ -8,7 +8,7 @@ const {
|
|
|
8
8
|
} = require('../model/csnUtils');
|
|
9
9
|
const { isBuiltinType } = require('../base/builtins');
|
|
10
10
|
const { isGeoTypeName } = require('../compiler/builtins');
|
|
11
|
-
const { setProp } = require('../
|
|
11
|
+
const { setProp } = require('../utils/objectUtils');
|
|
12
12
|
// Only to be used with validator.js - a correct `this` value needs to be provided!
|
|
13
13
|
|
|
14
14
|
/**
|
package/lib/checks/enricher.js
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
'use strict';
|
|
6
6
|
|
|
7
|
-
const { csnRefs } = require('../
|
|
8
|
-
const { setProp } = require('../
|
|
7
|
+
const { csnRefs } = require('../base/csnRefs');
|
|
8
|
+
const { setProp } = require('../utils/objectUtils');
|
|
9
9
|
const { isAnnotationExpression } = require('../base/builtins');
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -1,39 +1,69 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const { setProp } = require('../
|
|
3
|
+
const { setProp, forEachValue } = require('../utils/objectUtils');
|
|
4
4
|
const { featureFlags } = require('../transform/featureFlags');
|
|
5
5
|
const { isSqlService, isDummyService, isDataProductProductionService } = require('../transform/db/processSqlServices');
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
+
* Set a feature flag on the CSN model.
|
|
8
9
|
*
|
|
9
|
-
* @param {
|
|
10
|
+
* @param {CSN.Model} csn CSN model to set flag on
|
|
11
|
+
* @param {string} flag Flag name to set
|
|
12
|
+
*/
|
|
13
|
+
function setFeatureFlag( csn, flag ) {
|
|
14
|
+
if (!csn.meta)
|
|
15
|
+
setProp(csn, 'meta', {});
|
|
16
|
+
if (!csn.meta[featureFlags])
|
|
17
|
+
csn.meta[featureFlags] = {};
|
|
18
|
+
|
|
19
|
+
csn.meta[featureFlags][flag] = true;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Get a function that detects and sets feature flags for expand/inline columns in a query.
|
|
10
24
|
*
|
|
11
|
-
* @
|
|
25
|
+
* @param {CSN.Model} csn CSN model to set flags on
|
|
26
|
+
* @returns {Function} Function to call per query
|
|
12
27
|
*/
|
|
13
|
-
function
|
|
14
|
-
return function
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
28
|
+
function getQueryFeatureFlagSetter( csn ) {
|
|
29
|
+
return function setQueryFeatureFlags(query) {
|
|
30
|
+
const queryProp = query.SELECT ? 'SELECT' : 'projection';
|
|
31
|
+
query[queryProp]?.columns?.forEach((column) => {
|
|
32
|
+
if (column.expand || column.inline)
|
|
33
|
+
setFeatureFlag(csn, '$expandInline');
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
}
|
|
19
37
|
|
|
20
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Get a function that detects and sets feature flags for entity/service definitions.
|
|
40
|
+
* That are calculated elements and SQL services.
|
|
41
|
+
*
|
|
42
|
+
* @param {CSN.Model} csn CSN model to set flags on
|
|
43
|
+
* @param {CSN.Options} options Compiler options
|
|
44
|
+
* @returns {Function} Function to call per definition
|
|
45
|
+
*/
|
|
46
|
+
function getDefinitionFeatureFlagSetter( csn, options ) {
|
|
47
|
+
return function setDefinitionFeatureFlags(def) {
|
|
48
|
+
if (def.kind === 'entity' && def.elements) {
|
|
49
|
+
forEachValue(def.elements, (element) => {
|
|
50
|
+
if (element.value)
|
|
51
|
+
setFeatureFlag(csn, '$calculatedElements');
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
else if (def.kind === 'service') {
|
|
55
|
+
if (isSqlService(def))
|
|
56
|
+
setFeatureFlag(csn, '$sqlService');
|
|
57
|
+
if (isDummyService(def, options))
|
|
58
|
+
setFeatureFlag(csn, '$dummyService');
|
|
59
|
+
if (isDataProductProductionService(def))
|
|
60
|
+
setFeatureFlag(csn, '$dataProductService');
|
|
61
|
+
}
|
|
21
62
|
};
|
|
22
63
|
}
|
|
23
64
|
|
|
24
|
-
// Export
|
|
65
|
+
// Export factory functions that create bound feature flag setters for use in transformation loops
|
|
25
66
|
module.exports = {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
inline: setFeatureFlag('$expandInline'),
|
|
29
|
-
kind: function setFeatureFlagForSqlService( artifact ) {
|
|
30
|
-
if (isSqlService(artifact))
|
|
31
|
-
setFeatureFlag( '$sqlService' ).call(this);
|
|
32
|
-
|
|
33
|
-
if (isDummyService(artifact, this.options))
|
|
34
|
-
setFeatureFlag( '$dummyService' ).call(this);
|
|
35
|
-
|
|
36
|
-
if (isDataProductProductionService(artifact, this.options))
|
|
37
|
-
setFeatureFlag( '$dataProductService' ).call(this);
|
|
38
|
-
},
|
|
67
|
+
getQueryFeatureFlagSetter,
|
|
68
|
+
getDefinitionFeatureFlagSetter,
|
|
39
69
|
};
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Only to be used with validator.js - a correct this value needs to be provided!
|
|
4
4
|
|
|
5
5
|
const { ModelError } = require('../base/error');
|
|
6
|
-
const { setProp } = require('../
|
|
6
|
+
const { setProp } = require('../utils/objectUtils');
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Assert that targets of associations and compositions are entities.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { forEachGeneric } = require('../model/csnUtils');
|
|
4
4
|
const { otherSideIsExpandableStructure, resolveArtifactType } = require('./utils');
|
|
5
|
-
const { pathId } = require('../
|
|
5
|
+
const { pathId } = require('../base/csnRefs');
|
|
6
6
|
|
|
7
7
|
// Only to be used with validator.js - a correct this value needs to be provided!
|
|
8
8
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const { isPersistedOnDatabase, applyTransformationsOnNonDictionary } = require('../model/csnUtils');
|
|
4
4
|
const { isBuiltinType } = require('../base/builtins');
|
|
5
5
|
const { requireForeignKeyAccess } = require('./onConditions');
|
|
6
|
-
const { pathId } = require('../
|
|
6
|
+
const { pathId } = require('../base/csnRefs');
|
|
7
7
|
|
|
8
8
|
const generalQueryProperties = [ 'from', 'columns', 'where', 'groupBy', 'orderBy', 'having', 'limit' ];
|
|
9
9
|
|
package/lib/checks/validator.js
CHANGED
|
@@ -18,7 +18,6 @@ const validateHasPersistedElements = require('./hasPersistedElements');
|
|
|
18
18
|
const checkForHanaTypes = require('./checkForTypes');
|
|
19
19
|
const { checkAnnotationExpression } = require('./structuredAnnoExpressions');
|
|
20
20
|
const checkForParams = require('./parameters');
|
|
21
|
-
const checkAndRemoveEnums = require('./enums');
|
|
22
21
|
// forOdata
|
|
23
22
|
const { validateDefaultValues } = require('./defaultValues');
|
|
24
23
|
const { checkActionOrFunction } = require('./actionsFunctions');
|
|
@@ -54,7 +53,6 @@ const {
|
|
|
54
53
|
checkSqlAnnotationOnElement,
|
|
55
54
|
} = require('./sql-snippets');
|
|
56
55
|
const assertNoAssocUsageOutsideOfService = require('./assocOutsideService');
|
|
57
|
-
const featureFlags = require('./featureFlags');
|
|
58
56
|
const { timetrace } = require('../utils/timetrace');
|
|
59
57
|
|
|
60
58
|
const forRelationalDBMemberValidators
|
|
@@ -94,7 +92,6 @@ const forRelationalDBCsnValidators = [
|
|
|
94
92
|
navigationIntoMany,
|
|
95
93
|
expandToMany,
|
|
96
94
|
checkPathsInStoredCalcElement,
|
|
97
|
-
featureFlags,
|
|
98
95
|
];
|
|
99
96
|
/**
|
|
100
97
|
* @type {Array<(query: CSN.Query, path: CSN.Path) => void>}
|
|
@@ -168,7 +165,7 @@ function _validate( csn, that,
|
|
|
168
165
|
// TODO: Don't know if that's feasible? Do we really need to enrich annotations always?
|
|
169
166
|
// const { cleanup } = enrich(csn, { processAnnotations: that.options.tranformation === 'odata' });
|
|
170
167
|
|
|
171
|
-
applyTransformations(csn, mergeTransformers(csnValidators, that), [], { drillRef: true });
|
|
168
|
+
applyTransformations(csn, mergeTransformers(csnValidators, that), [], { drillRef: true, ...iterateOptions });
|
|
172
169
|
|
|
173
170
|
forEachDefinition(csn, (artifact, artifactName, prop, path) => {
|
|
174
171
|
artifactValidators.forEach((artifactValidator) => {
|
|
@@ -201,10 +198,8 @@ function _validate( csn, that,
|
|
|
201
198
|
function getDBCsnValidators( options ) {
|
|
202
199
|
const validations = [ ...forRelationalDBCsnValidators ];
|
|
203
200
|
|
|
204
|
-
if (options.transformation !== 'effective')
|
|
205
|
-
validations.push(checkAndRemoveEnums);
|
|
201
|
+
if (options.transformation !== 'effective')
|
|
206
202
|
validations.push(checkForParams.csnValidator);
|
|
207
|
-
}
|
|
208
203
|
|
|
209
204
|
if (options.sqlDialect === 'h2' || options.sqlDialect === 'postgres')
|
|
210
205
|
validations.push(checkForHanaTypes);
|
|
@@ -221,7 +216,13 @@ function forRelationalDB( csn, that ) {
|
|
|
221
216
|
const memberValidators = [ ...forRelationalDBMemberValidators, ...commonMemberValidators ];
|
|
222
217
|
if (that.options.transformation === 'hdbcds')
|
|
223
218
|
memberValidators.push(checkForParams.memberValidator);
|
|
224
|
-
|
|
219
|
+
// skip artifacts / elements which are not persisted on the database from being validated
|
|
220
|
+
const iterateOptions = {
|
|
221
|
+
skipArtifact: artifact => artifact.abstract ||
|
|
222
|
+
hasPersistenceSkipAnnotation(artifact) ||
|
|
223
|
+
artifact['@cds.persistence.exists'] ||
|
|
224
|
+
[ 'action', 'function', 'event' ].includes(artifact.kind),
|
|
225
|
+
};
|
|
225
226
|
return _validate(csn, that,
|
|
226
227
|
getDBCsnValidators(that.options),
|
|
227
228
|
memberValidators,
|
|
@@ -246,12 +247,7 @@ function forRelationalDB( csn, that ) {
|
|
|
246
247
|
}
|
|
247
248
|
),
|
|
248
249
|
forRelationalDBQueryValidators.concat(commonQueryValidators),
|
|
249
|
-
|
|
250
|
-
skipArtifact: artifact => artifact.abstract ||
|
|
251
|
-
hasPersistenceSkipAnnotation(artifact) ||
|
|
252
|
-
artifact['@cds.persistence.exists'] ||
|
|
253
|
-
[ 'action', 'function', 'event' ].includes(artifact.kind),
|
|
254
|
-
});
|
|
250
|
+
iterateOptions);
|
|
255
251
|
}
|
|
256
252
|
|
|
257
253
|
/**
|
package/lib/compiler/builtins.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
const { builtinLocation } = require('../base/location');
|
|
11
11
|
const { setLink } = require('./utils');
|
|
12
|
-
const { isBetaEnabled } = require('../base/
|
|
12
|
+
const { isBetaEnabled } = require('../base/specialOptions');
|
|
13
13
|
|
|
14
14
|
// TODO: make type parameters a dict
|
|
15
15
|
const core = {
|
package/lib/compiler/checks.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
11
11
|
|
|
12
|
-
const { isDeprecatedEnabled } = require('../base/
|
|
12
|
+
const { isDeprecatedEnabled } = require('../base/specialOptions');
|
|
13
13
|
const { propagationRules, acceptsExprValues } = require('../base/builtins');
|
|
14
14
|
const { typeParameters } = require('./builtins');
|
|
15
15
|
const {
|
|
@@ -132,8 +132,8 @@ function check( model ) {
|
|
|
132
132
|
typeName === 'cds.Vector' ||
|
|
133
133
|
typeName === 'cds.hana.CLOB' ||
|
|
134
134
|
typeName === 'cds.LargeBinary') {
|
|
135
|
-
warning( '
|
|
136
|
-
{
|
|
135
|
+
warning( 'type-invalid-for-key', [ elem.type?.location || elem.location, elem ],
|
|
136
|
+
{ type: typeName } );
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
|