@sap/cds-compiler 3.7.2 → 3.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 +63 -4
- package/bin/cdsc.js +3 -0
- package/doc/CHANGELOG_ARCHIVE.md +6 -6
- package/doc/CHANGELOG_BETA.md +15 -0
- package/doc/DeprecatedOptions_v2.md +1 -1
- package/doc/NameResolution.md +1 -1
- package/lib/api/main.js +61 -22
- package/lib/api/options.js +1 -0
- package/lib/api/validate.js +5 -0
- package/lib/base/dictionaries.js +5 -3
- package/lib/base/keywords.js +2 -0
- package/lib/base/message-registry.js +64 -22
- package/lib/base/messages.js +12 -7
- package/lib/base/model.js +3 -2
- package/lib/checks/arrayOfs.js +1 -1
- package/lib/checks/defaultValues.js +1 -1
- package/lib/checks/hasPersistedElements.js +1 -1
- package/lib/checks/invalidTarget.js +1 -1
- package/lib/checks/onConditions.js +9 -6
- package/lib/checks/sql-snippets.js +2 -2
- package/lib/checks/types.js +1 -2
- package/lib/compiler/assert-consistency.js +24 -5
- package/lib/compiler/base.js +49 -2
- package/lib/compiler/builtins.js +15 -6
- package/lib/compiler/checks.js +4 -4
- package/lib/compiler/define.js +59 -80
- package/lib/compiler/extend.js +701 -498
- package/lib/compiler/finalize-parse-cdl.js +4 -3
- package/lib/compiler/index.js +1 -1
- package/lib/compiler/kick-start.js +2 -2
- package/lib/compiler/populate.js +17 -9
- package/lib/compiler/propagator.js +12 -5
- package/lib/compiler/resolve.js +26 -173
- package/lib/compiler/shared.js +12 -53
- package/lib/compiler/tweak-assocs.js +1 -1
- package/lib/compiler/utils.js +2 -2
- package/lib/edm/annotations/genericTranslation.js +124 -46
- package/lib/edm/csn2edm.js +22 -1
- package/lib/edm/edmPreprocessor.js +41 -21
- package/lib/gen/Dictionary.json +4 -0
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +3 -1
- package/lib/gen/languageLexer.js +1 -1
- package/lib/gen/languageParser.js +4810 -4482
- package/lib/inspect/inspectPropagation.js +20 -36
- package/lib/json/from-csn.js +55 -5
- package/lib/json/to-csn.js +71 -110
- package/lib/language/errorStrategy.js +1 -0
- package/lib/language/genericAntlrParser.js +47 -8
- package/lib/language/language.g4 +88 -62
- package/lib/language/textUtils.js +13 -0
- package/lib/main.d.ts +43 -3
- package/lib/main.js +4 -2
- package/lib/model/csnRefs.js +14 -2
- package/lib/model/csnUtils.js +11 -74
- package/lib/model/revealInternalProperties.js +3 -0
- package/lib/optionProcessor.js +3 -0
- package/lib/render/toCdl.js +203 -104
- package/lib/render/toHdbcds.js +0 -1
- package/lib/render/toRename.js +14 -51
- package/lib/transform/braceExpression.js +6 -0
- package/lib/transform/db/rewriteCalculatedElements.js +55 -14
- package/lib/transform/forOdataNew.js +20 -15
- package/lib/transform/forRelationalDB.js +21 -14
- package/lib/transform/parseExpr.js +2 -0
- package/lib/transform/transformUtilsNew.js +36 -9
- package/lib/transform/translateAssocsToJoins.js +11 -4
- package/lib/transform/universalCsn/coreComputed.js +15 -7
- package/lib/transform/universalCsn/universalCsnEnricher.js +4 -4
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,67 @@
|
|
|
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.8.0 - 2023-03-27
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- compiler:
|
|
15
|
+
+ Table aliases for sub-queries are no longer required.
|
|
16
|
+
+ A time zone designator can now be used in time literals, e.g. `time'16:41:01+01:30'`or `time'16:41:01Z'`.
|
|
17
|
+
- Calculated elements ("on-read") are now enabled per default.
|
|
18
|
+
When used in views, they are replaced by their value, for example:
|
|
19
|
+
```cds
|
|
20
|
+
entity E { one: Integer; two = one + 1; };
|
|
21
|
+
entity P as projection on E { two };
|
|
22
|
+
// P is the same as:
|
|
23
|
+
entity P as projection on E { one + 1 as two };
|
|
24
|
+
```
|
|
25
|
+
This allows to define calculations centrally at the entity, which can be used by
|
|
26
|
+
other views.
|
|
27
|
+
- In CDL, a ternary operator was added as a shortcut for `CASE` expressions:
|
|
28
|
+
`a ? b : c` is a shortcut for `CASE WHEN a THEN b ELSE c END`. There is no CSN
|
|
29
|
+
representation. The ternary operator is rendered as a `CASE` expression in CSN.
|
|
30
|
+
- In CDL and CSN, `not null` can now also be used in type definitions.
|
|
31
|
+
- In CDL (and CSN as before), elements can be defined without specifying a type.
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- API: We now report an error for most backends, if the input CSN has
|
|
36
|
+
`meta.flavor == 'xtended'`, because only client/inferred CSN is supported.
|
|
37
|
+
- Update OData vocabularies 'PersonalData', 'UI'
|
|
38
|
+
- for.odata: Shortcut annotations `@label`, `@title`, `@description`, `@readonly` are no longer
|
|
39
|
+
removed from the OData processed CSN.
|
|
40
|
+
- to.cdl:
|
|
41
|
+
+ Annotation arrays are split into multiple lines, if a single line would be too long.
|
|
42
|
+
+ Nested `SELECT`s are put into separate lines to make them more readable.
|
|
43
|
+
+ (Annotation) paths are quoted less often.
|
|
44
|
+
- to.sql: The list of reserved SAP HANA identifiers was updated (for smart quoting).
|
|
45
|
+
|
|
46
|
+
### Fixed
|
|
47
|
+
|
|
48
|
+
- The CSN parser now accepts bare `list`s in `columns[]`, similar to the CDL parser.
|
|
49
|
+
- to.cdl:
|
|
50
|
+
+ Delimited identifiers in filters are now surrounded by spaces if necessary, to avoid `]]`
|
|
51
|
+
being interpreted as an escaped bracket.
|
|
52
|
+
- to.edm(x):
|
|
53
|
+
+ Remove empty `Edm.EntityContainer` again. Removal of an empty entity container has been
|
|
54
|
+
revoked with [3.5.0](#fixed-7) which was wrong. An empty container must not be rendered
|
|
55
|
+
as it is not spec compliant.
|
|
56
|
+
+ Correctly resolve chained enum symbols.
|
|
57
|
+
+ Fix a program abort during structured rendering in combination with `--odata-foreign-keys`
|
|
58
|
+
and foreign keys in structured types.
|
|
59
|
+
+ Correctly render paths to nested foreign keys as primary key in structured mode with
|
|
60
|
+
`--odata-foreign-keys`.
|
|
61
|
+
- to.hdi/to.sql/to.edm(x):
|
|
62
|
+
+ Reject unmanaged associations as ON-condition path end points.
|
|
63
|
+
+ Fix bug in message rendering for tuple expansion.
|
|
64
|
+
+ Correctly detect invalid @sql.append/prepend in projections.
|
|
65
|
+
- to.hdi/to.sql: The list of SAP HANA keywords was updated to the latest version.
|
|
66
|
+
|
|
67
|
+
### Removed
|
|
68
|
+
|
|
69
|
+
- for.odata: Undocumented shortcut annotation `@important` has been removed.
|
|
70
|
+
|
|
10
71
|
|
|
11
72
|
## Version 3.7.2 - 2023-02-24
|
|
12
73
|
|
|
@@ -15,6 +76,7 @@ The compiler behavior concerning `beta` features can change at any time without
|
|
|
15
76
|
- CSN parser: Structured annotations containing `=` were accidentally interpreted as expressions,
|
|
16
77
|
even though the corresponding beta flag was not set.
|
|
17
78
|
|
|
79
|
+
|
|
18
80
|
## Version 3.7.0 - 2023-02-22
|
|
19
81
|
|
|
20
82
|
### Added
|
|
@@ -44,9 +106,6 @@ The compiler behavior concerning `beta` features can change at any time without
|
|
|
44
106
|
explicit redirection.
|
|
45
107
|
- to.edm(x): Process value help list convenience annotations on unbound action parameters.
|
|
46
108
|
|
|
47
|
-
### Removed
|
|
48
|
-
|
|
49
|
-
- tbd
|
|
50
109
|
|
|
51
110
|
## Version 3.6.2 - 2023-02-06
|
|
52
111
|
|
|
@@ -455,7 +514,7 @@ The compiler behavior concerning `beta` features can change at any time without
|
|
|
455
514
|
+ Enforce `odata-spec-violation-key-null` on explicit foreign keys of managed primary key associations.
|
|
456
515
|
+ Proxies/service cross references are no longer created for associations with arbitrary ON conditions.
|
|
457
516
|
Only managed or `$self` backlink association targets are proxy/service cross reference candidates.
|
|
458
|
-
+ Explicit foreign keys of a managed association that are not a primary key in the target are exposed in the
|
|
517
|
+
+ Explicit foreign keys of a managed association that are not a primary key in the target are exposed in the proxy.
|
|
459
518
|
+ If an association is primary key, the resulting navigation property is set to `Nullable:false` in structured mode.
|
|
460
519
|
|
|
461
520
|
## Version 2.15.0 - 2022-05-06
|
package/bin/cdsc.js
CHANGED
|
@@ -353,6 +353,9 @@ function executeCommandLine( command, options, args ) {
|
|
|
353
353
|
options.odataFormat = 'structured';
|
|
354
354
|
options.odataContainment = true;
|
|
355
355
|
}
|
|
356
|
+
if (options.odataVocRefs && typeof options.odataVocRefs === 'string')
|
|
357
|
+
options.odataVocRefs = JSON.parse(options.odataVocRefs);
|
|
358
|
+
|
|
356
359
|
const csn = options.directBackend ? model : compactModel(model, options);
|
|
357
360
|
if (options.csn) {
|
|
358
361
|
const odataCsn = main.for.odata(csn, options);
|
package/doc/CHANGELOG_ARCHIVE.md
CHANGED
|
@@ -777,7 +777,7 @@ synchronously.
|
|
|
777
777
|
|
|
778
778
|
- Introduce annotation `@cds.redirection.target`.
|
|
779
779
|
With value `false`, the projection is not considered an implicit redirection target;
|
|
780
|
-
with value `true`, is
|
|
780
|
+
with value `true`, is considered a “preferred” redirection target.
|
|
781
781
|
|
|
782
782
|
## Version 1.49.2 - 2021-02-16
|
|
783
783
|
|
|
@@ -1313,7 +1313,7 @@ synchronously.
|
|
|
1313
1313
|
|
|
1314
1314
|
- HANA/SQL: Validate ON conditions of mixin association definitions in all subqueries
|
|
1315
1315
|
|
|
1316
|
-
- OData V2: Assign various `@sap` annotations to the `<edmx:
|
|
1316
|
+
- OData V2: Assign various `@sap` annotations to the `<edmx:entitySet>` and `<edmx:AssociationSet>`
|
|
1317
1317
|
if such annotations are assigned to CDS entities or associations.
|
|
1318
1318
|
|
|
1319
1319
|
- OData V4 Structured: Omit foreign keys of managed associations that establish the containment relationship to
|
|
@@ -1445,7 +1445,7 @@ synchronously.
|
|
|
1445
1445
|
|
|
1446
1446
|
### Fixed
|
|
1447
1447
|
|
|
1448
|
-
- Compiler: `type of <unmanaged
|
|
1448
|
+
- Compiler: `type of <unmanaged association>` is now handled correctly by raising an error.
|
|
1449
1449
|
|
|
1450
1450
|
## Version 1.25.0 - 2020-04-09
|
|
1451
1451
|
|
|
@@ -1629,7 +1629,7 @@ Fixes
|
|
|
1629
1629
|
* In the Hana/Sql backend, correctly resolve forward `on` condition when using
|
|
1630
1630
|
mixin association that backlinks to an unrelated 3rd party entity and association.
|
|
1631
1631
|
* Raise a warning if the element of the forward association and the element of
|
|
1632
|
-
the query source do not
|
|
1632
|
+
the query source do not originate from the same defining entity. Raise an
|
|
1633
1633
|
error if the element of the forward association cannot be found in the query
|
|
1634
1634
|
source or is ambiguous.
|
|
1635
1635
|
* Correctly create localization views with compiled model as input;
|
|
@@ -2267,7 +2267,7 @@ Changes
|
|
|
2267
2267
|
_Update to v1.12.1_ if you experience problems – an inherited `@cds.autoexpose` had not been considered.
|
|
2268
2268
|
* In `toSql` and `toHana` errors are raised
|
|
2269
2269
|
+ for duplicate definitions of elements that differ only in spelling,
|
|
2270
|
-
+ if the
|
|
2270
|
+
+ if the entity is not `abstract` or annotated with any `@cds.persistence` set to true and
|
|
2271
2271
|
- an element is typed to be an `array of` a `type`,
|
|
2272
2272
|
- an implicit managed composition has cardinality to many.
|
|
2273
2273
|
* Raise a warning if an element is to be `localized` which is not of type `cds.String`.
|
|
@@ -2489,7 +2489,7 @@ Fixes
|
|
|
2489
2489
|
while rewriting the `on` conditition of a projected association.
|
|
2490
2490
|
* Apply OData specific checks (e.g. that all elements of an entity must have a type)
|
|
2491
2491
|
applied only to objects that are exposed in a service.
|
|
2492
|
-
* When generating SQL for SQLite, replace the
|
|
2492
|
+
* When generating SQL for SQLite, replace the special variables `$now`, `$user.id`
|
|
2493
2493
|
and `$user.locale` by `CURRENT_TIMESTAMP`, `'$user.id'`, and `'EN'`, respectively.
|
|
2494
2494
|
* Issue a warning for conflicting cardinality declarations (e.g. `association[1] to many ...`).
|
|
2495
2495
|
* Handle filters with cardinality correctly when translating associations to joins.
|
package/doc/CHANGELOG_BETA.md
CHANGED
|
@@ -8,6 +8,21 @@ Note: `beta` fixes, changes and features are listed in this ChangeLog just for i
|
|
|
8
8
|
The compiler behavior concerning `beta` features can change at any time without notice.
|
|
9
9
|
**Don't use `beta` fixes, changes and features in productive mode.**
|
|
10
10
|
|
|
11
|
+
## Version 3.8.0 - 2023-03-27
|
|
12
|
+
|
|
13
|
+
### Added `v4preview`
|
|
14
|
+
|
|
15
|
+
This beta flags tries to imitate cds-compiler v4 behavior.
|
|
16
|
+
This includes new compiler messages as well as potentially breaking changes.
|
|
17
|
+
|
|
18
|
+
Enable this beta flag to ease upgrading to cds-compiler v4.
|
|
19
|
+
|
|
20
|
+
This flag does not guarantee full compatibility with v4, but only
|
|
21
|
+
helps to identify potential issues as soon as possible.
|
|
22
|
+
|
|
23
|
+
### Removed `calculatedElements`
|
|
24
|
+
|
|
25
|
+
Now enabled per default.
|
|
11
26
|
|
|
12
27
|
## Version 3.7.0 - 2023-02-22
|
|
13
28
|
|
|
@@ -51,7 +51,7 @@ The compiled model contains the following generated entities:
|
|
|
51
51
|
* the auto-exposed projection `our.Service.Proj.texts`
|
|
52
52
|
which is a composition target of `our.Service.Proj:texts`
|
|
53
53
|
|
|
54
|
-
For the following
|
|
54
|
+
For the following subsections (and in general), it is important to understand that
|
|
55
55
|
you can define all auto-exposed entities yourself (well, they are not
|
|
56
56
|
_auto_-exposed anymore)
|
|
57
57
|
_without_ any difference in the compiled model
|
package/doc/NameResolution.md
CHANGED
|
@@ -600,7 +600,7 @@ The list of search environments is created as follows:
|
|
|
600
600
|
|
|
601
601
|
The above mentioned `:`-escape mechanism leads to the following name resolution:
|
|
602
602
|
|
|
603
|
-
* The first lexical search environment is the
|
|
603
|
+
* The first lexical search environment is the environment containing all parameter names of the current view.
|
|
604
604
|
* The following search environments are the usual ones from the "main artifact name resolution";
|
|
605
605
|
constant values can be accessed this way (_TODO_: probably not now).
|
|
606
606
|
|
package/lib/api/main.js
CHANGED
|
@@ -335,7 +335,7 @@ function remapName( key, csn, filter = () => true ) {
|
|
|
335
335
|
* @param {CSN.Model} csn A clean input CSN representing the desired "after-image"
|
|
336
336
|
* @param {HdiOptions} options Options
|
|
337
337
|
* @param {CSN.Model} beforeImage A db-transformed CSN representing the "before-image", or null in case no such image
|
|
338
|
-
* is known, i.e. for the very first migration step
|
|
338
|
+
* is known, i.e. for the very first migration step.
|
|
339
339
|
* @returns {object} An object with three properties:
|
|
340
340
|
* - afterImage: A db-transformed CSN representing the "after-image"
|
|
341
341
|
* - drops: An array of SQL statements to drop views/tables
|
|
@@ -812,18 +812,21 @@ function publishCsnProcessor( processor, _name ) {
|
|
|
812
812
|
/**
|
|
813
813
|
* Function that calls the processor and re-compiles in case of internal errors
|
|
814
814
|
*
|
|
815
|
-
* @param {
|
|
816
|
-
* @param {
|
|
815
|
+
* @param {CSN.Model} csn CSN
|
|
816
|
+
* @param {CSN.Options} options Options
|
|
817
817
|
* @param {any} args Any additional arguments
|
|
818
818
|
* @returns {any} What ever the processor returns
|
|
819
819
|
*/
|
|
820
820
|
function api( csn, options = {}, ...args ) {
|
|
821
821
|
try {
|
|
822
|
-
|
|
823
|
-
|
|
822
|
+
const messageFunctions = messages.makeMessageFunction(csn, options, 'api');
|
|
823
|
+
if (options.deprecated)
|
|
824
824
|
checkRemovedDeprecatedFlags( options, messageFunctions );
|
|
825
|
-
|
|
826
|
-
checkOutdatedOptions( options );
|
|
825
|
+
|
|
826
|
+
checkOutdatedOptions( options, messageFunctions );
|
|
827
|
+
checkCsnFlavor( csn, options, messageFunctions, _name );
|
|
828
|
+
|
|
829
|
+
messageFunctions.throwWithError();
|
|
827
830
|
|
|
828
831
|
timetrace.timetrace.start(_name);
|
|
829
832
|
const result = processor( csn, options, ...args );
|
|
@@ -861,37 +864,73 @@ const oldBackendOptionNames = [ 'toSql', 'toOdata', 'toHana', 'forHana' ];
|
|
|
861
864
|
* - toOdata/toSql/toHana/forHana -> now flat options
|
|
862
865
|
*
|
|
863
866
|
* @param {CSN.Options} options Backend options
|
|
867
|
+
* @param {object} messageFunctions Functions returned by makeMessageFunction()
|
|
864
868
|
*/
|
|
865
|
-
function checkOutdatedOptions( options ) {
|
|
866
|
-
const { error, throwWithError } = messages.makeMessageFunction(null, options, 'api');
|
|
867
|
-
|
|
869
|
+
function checkOutdatedOptions( options, messageFunctions ) {
|
|
868
870
|
// This error has been emitted once, we don't need to emit it again.
|
|
869
|
-
if (options.messages?.some(m => m.messageId === 'api-invalid-option'))
|
|
870
|
-
throwWithError();
|
|
871
|
+
if (options.messages?.some(m => m.messageId === 'api-invalid-option' || m.messageId === 'api-invalid-variable-replacement'))
|
|
871
872
|
return;
|
|
872
|
-
|
|
873
|
+
|
|
873
874
|
|
|
874
875
|
for (const name of oldBackendOptionNames) {
|
|
875
876
|
if (typeof options[name] === 'object') // may be a boolean due to internal options
|
|
876
|
-
error('api-invalid-option', null, { '#': '
|
|
877
|
+
messageFunctions.error('api-invalid-option', null, { '#': 'deprecated', name });
|
|
877
878
|
}
|
|
878
879
|
|
|
879
880
|
if (options.magicVars)
|
|
880
|
-
error('api-invalid-option', null, { '#': 'magicVars' });
|
|
881
|
+
messageFunctions.error('api-invalid-option', null, { '#': 'magicVars', prop: 'magicVars', otherprop: 'variableReplacements' });
|
|
881
882
|
|
|
882
883
|
// Don't check `options.magicVars`. It's likely that the user renamed `magicVars` but
|
|
883
884
|
// forgot about user -> $user and locale -> $user.locale
|
|
884
|
-
if (options.variableReplacements?.user)
|
|
885
|
-
error('api-invalid-
|
|
886
|
-
|
|
887
|
-
|
|
885
|
+
if (options.variableReplacements?.user) {
|
|
886
|
+
messageFunctions.error('api-invalid-variable-replacement', null, {
|
|
887
|
+
'#': 'user', option: 'variableReplacements', prop: '$user', otherprop: 'user',
|
|
888
|
+
});
|
|
889
|
+
}
|
|
890
|
+
if (options.variableReplacements?.locale) {
|
|
891
|
+
messageFunctions.error('api-invalid-variable-replacement', null, {
|
|
892
|
+
'#': 'locale', option: 'variableReplacements', prop: '$user.locale', otherprop: 'locale',
|
|
893
|
+
});
|
|
894
|
+
}
|
|
888
895
|
|
|
889
896
|
forEachKey(options.variableReplacements || {}, (name) => {
|
|
890
|
-
if (!name.startsWith('$') && name !== 'user' && name !== 'locale')
|
|
891
|
-
error('api-invalid-
|
|
897
|
+
if (!name.startsWith('$') && name !== 'user' && name !== 'locale') {
|
|
898
|
+
messageFunctions.error('api-invalid-variable-replacement', null, {
|
|
899
|
+
'#': 'noDollar', option: 'variableReplacements', code: '$', name,
|
|
900
|
+
});
|
|
901
|
+
}
|
|
892
902
|
});
|
|
903
|
+
}
|
|
893
904
|
|
|
894
|
-
|
|
905
|
+
/**
|
|
906
|
+
* Checks that the given CSN is usable by our backends, e.g. that
|
|
907
|
+
* the CSN is not a gensrc (a.k.a. xtended) for most backends.
|
|
908
|
+
*
|
|
909
|
+
* For reference, cds-compiler/cds-dk CSN flavor map:
|
|
910
|
+
* - client -> inferred
|
|
911
|
+
* - gensrc -> xtended
|
|
912
|
+
* - parseCdl -> parsed
|
|
913
|
+
*
|
|
914
|
+
* If this function becomes more complex (e.g. more module conditions),
|
|
915
|
+
* move it from then generic api wrapper to the individual module.
|
|
916
|
+
*
|
|
917
|
+
* TODO: The compiler does not set any marker in `meta`; we use the umbrella one
|
|
918
|
+
* for easier debugging.
|
|
919
|
+
*
|
|
920
|
+
* @param {CSN.Model} csn User CSN
|
|
921
|
+
* @param {CSN.Options} options User options
|
|
922
|
+
* @param {object} messageFunctions Functions returned by makeMessageFunction()
|
|
923
|
+
* @param {string} module Backend module, e.g. to.cdl or to.sql
|
|
924
|
+
*/
|
|
925
|
+
function checkCsnFlavor( csn, options, messageFunctions, module ) {
|
|
926
|
+
if (module === 'to.cdl' || !csn)
|
|
927
|
+
return; // to.cdl allows every CSN flavor
|
|
928
|
+
|
|
929
|
+
if (csn.meta?.flavor === 'xtended') {
|
|
930
|
+
// TODO: csn.meta?.flavor === 'parsed'; currently used by `@sap/cds` tests.
|
|
931
|
+
messageFunctions.error('api-unsupported-csn-flavor', null, { name: module, option: csn.meta?.flavor },
|
|
932
|
+
'Module $(NAME) expects a client/inferred CSN, not $(OPTION)');
|
|
933
|
+
}
|
|
895
934
|
}
|
|
896
935
|
|
|
897
936
|
/**
|
package/lib/api/options.js
CHANGED
package/lib/api/validate.js
CHANGED
|
@@ -82,6 +82,11 @@ const validators = {
|
|
|
82
82
|
sqlMapping: generateStringValidator([ 'plain', 'quoted', 'hdbcds' ]),
|
|
83
83
|
odataVersion: generateStringValidator([ 'v2', 'v4' ]),
|
|
84
84
|
odataFormat: generateStringValidator([ 'flat', 'structured' ]),
|
|
85
|
+
odataVocRefs: {
|
|
86
|
+
validate: val => (typeof val === 'object' && !Array.isArray(val)),
|
|
87
|
+
expected: () => 'type JSON object',
|
|
88
|
+
found: val => `type ${ Array.isArray(val) ? 'JSON array' : typeof val }`,
|
|
89
|
+
},
|
|
85
90
|
service: {
|
|
86
91
|
validate: val => typeof val === 'string',
|
|
87
92
|
expected: () => 'type string',
|
package/lib/base/dictionaries.js
CHANGED
|
@@ -91,11 +91,13 @@ function dictFirst( dict ) {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
// Push `entry` to the array value with key `name` in the dictionary `dict`.
|
|
94
|
-
function pushToDict( dict, name,
|
|
94
|
+
function pushToDict( dict, name, ...entries ) {
|
|
95
95
|
if (dict[name])
|
|
96
|
-
dict[name].push(
|
|
96
|
+
dict[name].push( ...entries );
|
|
97
|
+
else if (name.charAt(0) !== '_')
|
|
98
|
+
dict[name] = entries;
|
|
97
99
|
else
|
|
98
|
-
dict
|
|
100
|
+
Object.defineProperty( dict, name, { value: entries, configurable: true, writable: true } );
|
|
99
101
|
}
|
|
100
102
|
|
|
101
103
|
module.exports = {
|
package/lib/base/keywords.js
CHANGED
|
@@ -579,6 +579,7 @@ module.exports = {
|
|
|
579
579
|
'ST_ALPHASHAPEAGGR',
|
|
580
580
|
'ST_ALPHASHAPEAREAAGGR',
|
|
581
581
|
'ST_ALPHASHAPEEDGEAGGR',
|
|
582
|
+
'ST_ASGEOJSON',
|
|
582
583
|
'ST_ASMVT',
|
|
583
584
|
'ST_ASSVGAGGR',
|
|
584
585
|
'ST_CIRCULARSTRING',
|
|
@@ -606,6 +607,7 @@ module.exports = {
|
|
|
606
607
|
'ST_INTERSECTIONAGGR',
|
|
607
608
|
'ST_LINESTRING',
|
|
608
609
|
'ST_MAKELINE',
|
|
610
|
+
'ST_MAKELINEAGGR',
|
|
609
611
|
'ST_MAKEPOLYGON',
|
|
610
612
|
'ST_MEMORY_LOB',
|
|
611
613
|
'ST_MULTILINESTRING',
|
|
@@ -60,7 +60,7 @@ const centralMessages = {
|
|
|
60
60
|
'anno-undefined-def': { severity: 'Warning' }, // for annotate statement (for CSN or CDL path cont)
|
|
61
61
|
'anno-undefined-element': { severity: 'Warning' },
|
|
62
62
|
'anno-undefined-param': { severity: 'Warning' },
|
|
63
|
-
'anno-unexpected-ellipsis
|
|
63
|
+
'anno-unexpected-ellipsis': { severity: 'Error', configurableFor: 'v3' },
|
|
64
64
|
|
|
65
65
|
'args-expected-named': { severity: 'Error', configurableFor: 'deprecated' }, // future --sloppy
|
|
66
66
|
'args-no-params': { severity: 'Error', configurableFor: 'deprecated' }, // future --sloppy
|
|
@@ -185,6 +185,7 @@ const centralMessages = {
|
|
|
185
185
|
'odata-spec-violation-property-name': { severity: 'Warning' }, // more than 30 chars
|
|
186
186
|
'odata-anno-preproc': { severity: 'Warning', configurableFor: true },
|
|
187
187
|
'odata-anno-dict': { severity: 'Warning', configurableFor: true },
|
|
188
|
+
'odata-anno-vocref': { severity: 'Warning', configurableFor: true },
|
|
188
189
|
'odata-anno-dict-enum': { severity: 'Error' },
|
|
189
190
|
'odata-anno-value': { severity: 'Warning', configurableFor: true },
|
|
190
191
|
'odata-anno-type': { severity: 'Warning', configurableFor: true },
|
|
@@ -220,13 +221,16 @@ for (const oldName in oldMessageIds) {
|
|
|
220
221
|
|
|
221
222
|
const centralMessageTexts = {
|
|
222
223
|
'api-invalid-option': {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
224
|
+
std: 'Invalid option $(NAME)!',
|
|
225
|
+
deprecated: 'Option $(NAME) is no longer supported! Use latest API options instead',
|
|
226
|
+
magicVars: 'Option $(PROP) is no longer supported! Use $(OTHERPROP) instead. See <https://cap.cloud.sap/docs/guides/databases#configuring-variables> for details',
|
|
227
|
+
},
|
|
228
|
+
|
|
229
|
+
'api-invalid-variable-replacement': {
|
|
230
|
+
std: 'Option $(OPTION) does not support $(NAME)',
|
|
231
|
+
user: 'Option $(OPTION) expects $(PROP) instead of $(OTHERPROP). See <https://cap.cloud.sap/docs/guides/databases#configuring-variables> for details',
|
|
232
|
+
locale: 'Option $(OPTION) expects $(PROP) instead of $(OTHERPROP). See <https://cap.cloud.sap/docs/guides/databases#configuring-variables> for details',
|
|
233
|
+
'noDollar': 'Option $(OPTION) does not know $(NAME). Did you forget a leading $(CODE)?'
|
|
230
234
|
},
|
|
231
235
|
|
|
232
236
|
'anno-duplicate': {
|
|
@@ -244,7 +248,6 @@ const centralMessageTexts = {
|
|
|
244
248
|
'anno-unstable-array': 'Unstable order of array items due to repeated assignments for $(ANNO)',
|
|
245
249
|
'anno-mismatched-ellipsis': 'An array with $(CODE) can only be used if there is an assignment below with an array value',
|
|
246
250
|
'anno-unexpected-ellipsis': 'No base annotation available to apply $(CODE)',
|
|
247
|
-
'anno-unexpected-ellipsis-layers': 'No base annotation available to apply $(CODE)',
|
|
248
251
|
'chained-array-of': '"Array of"/"many" must not be chained with another "array of"/"many" inside a service',
|
|
249
252
|
|
|
250
253
|
'check-proper-type-of': {
|
|
@@ -268,6 +271,12 @@ const centralMessageTexts = {
|
|
|
268
271
|
mixin: 'A mixin name starting with $(NAME) might shadow a special variable - replace by another name',
|
|
269
272
|
},
|
|
270
273
|
|
|
274
|
+
'name-missing-alias': {
|
|
275
|
+
std: 'Missing table alias for this subquery',
|
|
276
|
+
duplicate: 'Missing table alias for this subquery; add $(CODE) to fix name clash of internal and explicit table alias',
|
|
277
|
+
hdbcds: 'Missing table alias for a subquery; SAP HANA CDS requires table aliases'
|
|
278
|
+
},
|
|
279
|
+
|
|
271
280
|
// Syntax messages, both CDL and CSN parser: ----------------------------------
|
|
272
281
|
'syntax-deprecated-abstract': {
|
|
273
282
|
std: 'Abstract entity definitions are deprecated; use aspect definitions instead',
|
|
@@ -300,9 +309,9 @@ const centralMessageTexts = {
|
|
|
300
309
|
'std': 'Invalid literal value',
|
|
301
310
|
'uneven-hex': 'A binary literal must have an even number of characters',
|
|
302
311
|
'invalid-hex': 'A binary literal must only contain characters ‹0-9›, ‹a-f› and ‹A-F›',
|
|
303
|
-
'time': 'A time literal must look like ‹hh:mm:ss› or ‹hh:mm› where each letter represents a digit',
|
|
312
|
+
'time': 'A time literal must look like ‹hh:mm:ss› or ‹hh:mm› where each letter represents a digit. A timezone is optional',
|
|
304
313
|
'date': 'A date literal must look like ‹YYYY-MM-DD› where each letter represents a digit',
|
|
305
|
-
'timestamp': 'A timestamp literal must look like ‹YYYY-MM-DD hh:mm:ss.u…u› or ‹YYYY-MM-DD hh:mm› where each letter represents a digit, ‹u…u› represents 1 to 7 digits',
|
|
314
|
+
'timestamp': 'A timestamp literal must look like ‹YYYY-MM-DD hh:mm:ss.u…u› or ‹YYYY-MM-DD hh:mm› where each letter represents a digit, ‹u…u› represents 1 to 7 digits. A timezone is optional',
|
|
306
315
|
'number': 'The string value in property $(PROP) does not represent a number',
|
|
307
316
|
'expecting': 'Expecting literal type $(OP) for the value in property $(OTHERPROP)',
|
|
308
317
|
'typeof': 'String $(RAWVALUE) is no valid literal type for the string value in property $(OTHERPROP)',
|
|
@@ -384,6 +393,10 @@ const centralMessageTexts = {
|
|
|
384
393
|
'zero-parens': 'Deprecated CSN v.0.1.0 representation of expressions in parentheses',
|
|
385
394
|
'zero-replace': 'Replace CSN v0.1.0 value in $(PROP) by $(VALUE)',
|
|
386
395
|
},
|
|
396
|
+
'syntax-deprecated-type-ref': {
|
|
397
|
+
std: 'Expecting a string as value for property $(PROP) for a reference to a definition',
|
|
398
|
+
'ref-item': 'Expecting a string as value for property $(PROP) for a type reference to an element',
|
|
399
|
+
},
|
|
387
400
|
|
|
388
401
|
'syntax-expecting-object': {
|
|
389
402
|
std: 'Expecting object for property $(PROP)',
|
|
@@ -438,6 +451,12 @@ const centralMessageTexts = {
|
|
|
438
451
|
annotation: 'Annotation definitions can\'t have calculated elements',
|
|
439
452
|
param: 'Parameters can\'t have calculated elements',
|
|
440
453
|
},
|
|
454
|
+
'ref-invalid-calc-elem': {
|
|
455
|
+
std: 'Can\'t include artifact with calculated element',
|
|
456
|
+
event: 'An event can\'t include an entity with calculated elements',
|
|
457
|
+
type: 'A type can\'t include an entity with calculated elements',
|
|
458
|
+
annotation: 'An annotation can\'t include an entity with calculated elements',
|
|
459
|
+
},
|
|
441
460
|
'def-unsupported-calc-elem': {
|
|
442
461
|
std: 'Calculated elements are not supported',
|
|
443
462
|
nested: 'Calculated elements in structures are not supported, yet'
|
|
@@ -526,6 +545,7 @@ const centralMessageTexts = {
|
|
|
526
545
|
'ref-unexpected-navigation': {
|
|
527
546
|
std: 'Can\'t follow association $(ID) of path $(ELEMREF) in an ON-condition; only foreign keys can be referred to, but not $(NAME)',
|
|
528
547
|
unmanaged: 'Can\'t follow unmanaged association $(ID) of path $(ELEMREF) in an ON-condition; only foreign keys can be referred to',
|
|
548
|
+
unmanagedleaf: 'Unexpected unmanged association as final path step of $(ELEMREF) in an ON-condition',
|
|
529
549
|
},
|
|
530
550
|
|
|
531
551
|
'type-unexpected-typeof': {
|
|
@@ -557,15 +577,21 @@ const centralMessageTexts = {
|
|
|
557
577
|
element: 'Artifact $(ART) has no element $(NAME)',
|
|
558
578
|
enum: 'Artifact $(ART) has no enum $(NAME)',
|
|
559
579
|
returns: 'Return value of $(ART) has no element $(NAME)',
|
|
560
|
-
'
|
|
580
|
+
'enum-returns': 'Return value of $(ART) has no enum $(NAME)',
|
|
561
581
|
},
|
|
562
582
|
'anno-undefined-action': {
|
|
563
583
|
std: 'Action $(ART) has not been found',
|
|
564
|
-
action: 'Artifact $(ART) has no action $(
|
|
584
|
+
action: 'Artifact $(ART) has no action $(NAME)'
|
|
565
585
|
},
|
|
566
586
|
'anno-undefined-param': {
|
|
567
587
|
std: 'Parameter $(ART) has not been found',
|
|
568
|
-
param: 'Artifact $(ART) has no parameter $(
|
|
588
|
+
param: 'Artifact $(ART) has no parameter $(NAME)'
|
|
589
|
+
},
|
|
590
|
+
|
|
591
|
+
// annotation checks against their definition
|
|
592
|
+
'anno-expecting-value': {
|
|
593
|
+
'std': 'Expecting a value for the annotation; see annotation definition for $(ANNO)',
|
|
594
|
+
'type': 'Expecting a value of type $(TYPE) for the annotation'
|
|
569
595
|
},
|
|
570
596
|
|
|
571
597
|
'def-unexpected-paramview-assoc': {
|
|
@@ -622,7 +648,10 @@ const centralMessageTexts = {
|
|
|
622
648
|
action: 'Duplicate definition of action or function $(NAME)',
|
|
623
649
|
param: 'Duplicate definition of parameter $(NAME)',
|
|
624
650
|
alias: 'Duplicate definition of table alias or mixin $(NAME)',
|
|
651
|
+
'include-elements': 'Duplicate element $(NAME) through multiple includes $(SORTED_ARTS)',
|
|
652
|
+
'include-actions': 'Duplicate action or function $(NAME) through multiple includes $(SORTED_ARTS)',
|
|
625
653
|
},
|
|
654
|
+
// TODO: Remove in v4, use duplicate-definition
|
|
626
655
|
'ref-duplicate-include-member': {
|
|
627
656
|
std: 'Duplicate member $(NAME) through multiple includes $(SORTED_ARTS)',
|
|
628
657
|
elements: 'Duplicate element $(NAME) through multiple includes $(SORTED_ARTS)',
|
|
@@ -645,18 +674,18 @@ const centralMessageTexts = {
|
|
|
645
674
|
'extend-unexpected-include': 'Can\'t extend $(META) with includes',
|
|
646
675
|
'ref-expecting-bare-aspect': 'An aspect without elements is expected here',
|
|
647
676
|
|
|
677
|
+
'ext-duplicate-same-file': 'Duplicate extension with $(PROP) in same file',
|
|
648
678
|
'ext-duplicate-extend-type': 'Duplicate type extension for type $(TYPE)',
|
|
649
679
|
'ext-duplicate-extend-type-unrelated-layer': 'Duplicate type extension for type $(TYPE)',
|
|
650
680
|
'ext-invalid-type-property': {
|
|
651
|
-
std: '
|
|
652
|
-
'
|
|
681
|
+
std: 'Type property $(PROP) can only be extended',
|
|
682
|
+
'indirect': 'Type property $(PROP) can only be extended if directly provided at the definition',
|
|
683
|
+
'new-prop': 'Type property $(PROP) can only be extended, not added',
|
|
684
|
+
string: 'Only numerical properties can be extended, but found string for $(PROP)',
|
|
653
685
|
// eslint-disable-next-line max-len
|
|
654
|
-
|
|
686
|
+
number: 'Value of type property $(PROP) must be $(NUMBER) or higher, it can\'t be smaller than originally provided',
|
|
655
687
|
// eslint-disable-next-line max-len
|
|
656
|
-
|
|
657
|
-
prop: 'Type property $(PROP) can\'t be extended',
|
|
658
|
-
scale: 'If property $(PROP) is increased, then so must $(OTHERPROP)',
|
|
659
|
-
string: 'Only numerical properties can be extended, but found string for $(PROP)',
|
|
688
|
+
scale: 'With the extension for type property $(OTHERPROP), the value of $(PROP) must be $(NUMBER) or higher',
|
|
660
689
|
},
|
|
661
690
|
'ref-expected-scalar-type': {
|
|
662
691
|
std: 'Only scalar type definitions can be extended with type properties',
|
|
@@ -687,6 +716,12 @@ const centralMessageTexts = {
|
|
|
687
716
|
'ref-sloppy-target': 'An entity or an aspect (not type) is expected here',
|
|
688
717
|
'ref-sloppy-event-type': 'A type, an element, an event, or a service entity is expected here',
|
|
689
718
|
|
|
719
|
+
'ref-ambiguous': {
|
|
720
|
+
std: 'Replace ambiguous $(ID) by $(NAMES)',
|
|
721
|
+
few: 'Replace ambiguous $(ID) by $(NAMES) or a new table alias for sub-queries that don\'t have one',
|
|
722
|
+
none: 'Ambiguous $(ID) requires an explicit table alias, but there are none: add table aliases to all sub-queries to disambiguate $(ID)',
|
|
723
|
+
},
|
|
724
|
+
|
|
690
725
|
'type-managed-composition': {
|
|
691
726
|
std: 'Managed compositions can\'t be used in types', // yet
|
|
692
727
|
sub: 'Managed compositions can\'t be used in sub elements',
|
|
@@ -713,7 +748,8 @@ const centralMessageTexts = {
|
|
|
713
748
|
'odata-spec-violation-id': {
|
|
714
749
|
std: 'Expected EDM name $(ID) to start with a letter or underscore, followed by at most 127 letters, underscores or digits',
|
|
715
750
|
'v2firstchar': 'Unexpected first character $(PROP) of EDM Name $(ID) for OData $(VERSION)',
|
|
716
|
-
'qualifier': 'Expected annotation qualifier $(ID) to start with a letter or underscore, followed by at most 127 letters, underscores or digits'
|
|
751
|
+
'qualifier': 'Expected annotation qualifier $(ID) to start with a letter or underscore, followed by at most 127 letters, underscores or digits',
|
|
752
|
+
'vocrefalias': 'Expected value $(VALUE) of vocabulary reference attribute $(ID) to start with a letter or underscore, followed by at most 127 letters, underscores or digits'
|
|
717
753
|
},
|
|
718
754
|
// version independent messages
|
|
719
755
|
'odata-spec-violation-key-array': {
|
|
@@ -782,6 +818,12 @@ const centralMessageTexts = {
|
|
|
782
818
|
'experimental': '$(ANNO) is experimental and can be changed or removed at any time, do not use productively!',
|
|
783
819
|
'redefinition': '$(ANNO) is an official OASIS/SAP annotation and can\'t be redefined'
|
|
784
820
|
},
|
|
821
|
+
'odata-anno-vocref': {
|
|
822
|
+
'std': 'Vocabulary reference $(ID) doesn\'t match alias $(NAME), reference is ignored',
|
|
823
|
+
'redef': 'Vocabulary reference $(ID) is the alias of the official OASIS/SAP vocabulary $(TYPE) which can\'t be redefined, reference is ignored',
|
|
824
|
+
'service': 'Vocabulary reference collides with service $(NAME), reference is ignored',
|
|
825
|
+
'malformed': 'Vocabulary reference $(ID) has invalid or missing value for attribute $(NAME), reference is ignored'
|
|
826
|
+
},
|
|
785
827
|
'odata-anno-dict-enum': {
|
|
786
828
|
'std' : 'Unexpected annotation definition $(NAME) with many enum type',
|
|
787
829
|
'type': 'Unexpected annotation definition $(NAME) with many enum type $(TYPE)',
|