@sap/cds-compiler 2.12.0 → 2.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/CHANGELOG.md +221 -15
  2. package/bin/cdsc.js +125 -50
  3. package/bin/cdsse.js +2 -2
  4. package/doc/CHANGELOG_BETA.md +13 -6
  5. package/doc/CHANGELOG_DEPRECATED.md +22 -6
  6. package/doc/NameResolution.md +21 -16
  7. package/lib/api/main.js +47 -84
  8. package/lib/api/options.js +5 -6
  9. package/lib/api/validate.js +6 -11
  10. package/lib/backends.js +15 -23
  11. package/lib/base/dictionaries.js +0 -8
  12. package/lib/base/error.js +26 -0
  13. package/lib/base/keywords.js +7 -17
  14. package/lib/base/location.js +9 -4
  15. package/lib/base/message-registry.js +114 -18
  16. package/lib/base/messages.js +101 -90
  17. package/lib/base/model.js +2 -63
  18. package/lib/base/optionProcessorHelper.js +177 -123
  19. package/lib/checks/annotationsOData.js +12 -33
  20. package/lib/checks/arrayOfs.js +1 -34
  21. package/lib/checks/cdsPersistence.js +2 -1
  22. package/lib/checks/enricher.js +17 -1
  23. package/lib/checks/invalidTarget.js +3 -1
  24. package/lib/checks/managedWithoutKeys.js +3 -1
  25. package/lib/checks/selectItems.js +4 -4
  26. package/lib/checks/sql-snippets.js +27 -26
  27. package/lib/checks/types.js +1 -1
  28. package/lib/checks/validator.js +6 -11
  29. package/lib/compiler/assert-consistency.js +6 -3
  30. package/lib/compiler/base.js +1 -0
  31. package/lib/compiler/builtins.js +19 -6
  32. package/lib/compiler/checks.js +23 -60
  33. package/lib/compiler/cycle-detector.js +1 -1
  34. package/lib/compiler/define.js +1151 -0
  35. package/lib/compiler/extend.js +1000 -0
  36. package/lib/compiler/finalize-parse-cdl.js +237 -0
  37. package/lib/compiler/index.js +107 -39
  38. package/lib/compiler/kick-start.js +190 -0
  39. package/lib/compiler/moduleLayers.js +4 -4
  40. package/lib/compiler/populate.js +1227 -0
  41. package/lib/compiler/propagator.js +114 -46
  42. package/lib/compiler/resolve.js +1521 -0
  43. package/lib/compiler/shared.js +126 -65
  44. package/lib/compiler/tweak-assocs.js +535 -0
  45. package/lib/compiler/utils.js +197 -33
  46. package/lib/edm/.eslintrc.json +5 -0
  47. package/lib/edm/annotations/genericTranslation.js +38 -24
  48. package/lib/edm/annotations/preprocessAnnotations.js +2 -2
  49. package/lib/edm/csn2edm.js +219 -100
  50. package/lib/edm/edm.js +302 -230
  51. package/lib/edm/edmPreprocessor.js +554 -419
  52. package/lib/edm/edmUtils.js +138 -44
  53. package/lib/gen/Dictionary.json +100 -19
  54. package/lib/gen/language.checksum +1 -1
  55. package/lib/gen/language.interp +11 -1
  56. package/lib/gen/language.tokens +86 -83
  57. package/lib/gen/languageLexer.interp +10 -1
  58. package/lib/gen/languageLexer.js +860 -833
  59. package/lib/gen/languageLexer.tokens +78 -75
  60. package/lib/gen/languageParser.js +5765 -4480
  61. package/lib/json/csnVersion.js +10 -11
  62. package/lib/json/from-csn.js +15 -3
  63. package/lib/json/to-csn.js +126 -68
  64. package/lib/language/docCommentParser.js +4 -4
  65. package/lib/language/genericAntlrParser.js +123 -5
  66. package/lib/language/language.g4 +355 -156
  67. package/lib/language/multiLineStringParser.js +5 -5
  68. package/lib/main.d.ts +486 -59
  69. package/lib/main.js +41 -9
  70. package/lib/model/api.js +3 -1
  71. package/lib/model/csnRefs.js +252 -156
  72. package/lib/model/csnUtils.js +384 -297
  73. package/lib/model/enrichCsn.js +71 -29
  74. package/lib/model/revealInternalProperties.js +29 -8
  75. package/lib/model/sortViews.js +2 -1
  76. package/lib/modelCompare/compare.js +23 -18
  77. package/lib/optionProcessor.js +63 -26
  78. package/lib/render/manageConstraints.js +35 -32
  79. package/lib/render/toCdl.js +897 -947
  80. package/lib/render/toHdbcds.js +205 -257
  81. package/lib/render/toSql.js +264 -225
  82. package/lib/render/utils/common.js +136 -25
  83. package/lib/render/utils/sql.js +4 -3
  84. package/lib/render/utils/stringEscapes.js +111 -0
  85. package/lib/sql-identifier.js +1 -1
  86. package/lib/transform/.eslintrc.json +5 -0
  87. package/lib/transform/db/.eslintrc.json +3 -1
  88. package/lib/transform/db/applyTransformations.js +35 -12
  89. package/lib/transform/db/assertUnique.js +1 -1
  90. package/lib/transform/db/associations.js +104 -306
  91. package/lib/transform/db/cdsPersistence.js +2 -2
  92. package/lib/transform/db/constraints.js +58 -53
  93. package/lib/transform/db/expansion.js +60 -33
  94. package/lib/transform/db/flattening.js +582 -104
  95. package/lib/transform/db/groupByOrderBy.js +3 -1
  96. package/lib/transform/db/transformExists.js +66 -13
  97. package/lib/transform/db/views.js +11 -7
  98. package/lib/transform/draft/.eslintrc.json +38 -0
  99. package/lib/transform/{db/draft.js → draft/db.js} +6 -5
  100. package/lib/transform/draft/odata.js +227 -0
  101. package/lib/transform/forHanaNew.js +109 -208
  102. package/lib/transform/forOdataNew.js +59 -212
  103. package/lib/transform/localized.js +46 -26
  104. package/lib/transform/odata/toFinalBaseType.js +85 -11
  105. package/lib/transform/odata/typesExposure.js +147 -199
  106. package/lib/transform/odata/utils.js +2 -2
  107. package/lib/transform/transformUtilsNew.js +44 -33
  108. package/lib/transform/translateAssocsToJoins.js +3 -20
  109. package/lib/transform/universalCsn/.eslintrc.json +36 -0
  110. package/lib/transform/universalCsn/coreComputed.js +172 -0
  111. package/lib/transform/universalCsn/universalCsnEnricher.js +737 -0
  112. package/lib/transform/universalCsn/utils.js +63 -0
  113. package/lib/utils/moduleResolve.js +13 -6
  114. package/lib/utils/objectUtils.js +30 -0
  115. package/package.json +1 -1
  116. package/share/messages/README.md +26 -0
  117. package/share/messages/message-explanations.json +2 -1
  118. package/share/messages/syntax-expected-integer.md +37 -0
  119. package/lib/compiler/definer.js +0 -2361
  120. package/lib/compiler/resolver.js +0 -3079
  121. package/lib/transform/odata/attachPath.js +0 -96
  122. package/lib/transform/odata/expandStructKeysInAssociations.js +0 -59
  123. package/lib/transform/odata/generateForeignKeyElements.js +0 -261
  124. package/lib/transform/odata/referenceFlattener.js +0 -290
  125. package/lib/transform/odata/sortByAssociationDependency.js +0 -105
  126. package/lib/transform/odata/structuralPath.js +0 -72
  127. package/lib/transform/odata/structureFlattener.js +0 -171
  128. package/lib/transform/universalCsnEnricher.js +0 -237
package/CHANGELOG.md CHANGED
@@ -7,6 +7,212 @@
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 2.15.2 - 2022-05-12
12
+
13
+ ### Fixed
14
+
15
+ - Option `cdsHome` can be used instead of `global.cds.home` to specify the path to `@sap/cds/`.
16
+ - to.edm(x):
17
+ + Set anonymous nested proxy key elements to `Nullable:false` until first named type is reached.
18
+ + Enforce `odata-spec-violation-key-null` on explicit foreign keys of managed primary key associations.
19
+ + Proxies/service cross references are no longer created for associations with arbitrary ON conditions.
20
+ Only managed or `$self` backlink association targets are proxy/service cross reference candidates.
21
+ + Explicit foreign keys of a managed association that are not a primary key in the target are exposed in the the proxy.
22
+ + If an association is primary key, the resulting navigation property is set to `Nullable:false` in structured mode.
23
+
24
+ ## Version 2.15.0 - 2022-05-06
25
+
26
+ ### Added
27
+
28
+ - A new warning is emitted if `excluding` is used without a wildcard, since this does
29
+ not have any effect.
30
+ - All scalar types can now take named arguments, e.g. `MyString(length: 10)`.
31
+ For custom scalar types, one unnamed arguments is interpreted as length, two arguments are interpreted
32
+ as precision and scale, e.g. `MyDecimal(3,3)`.
33
+ - If the type `sap.common.Locale` exists, it will be used as type for the `locale` element
34
+ of generated texts entities. The type must be a `cds.String`.
35
+ - to.cdl: Extend statements (from `extensions`) can now be rendered.
36
+ - Add OData vocabulary 'Hierarchy'.
37
+ - CDL: New associations can be published in queries, e.g. `assoc : Association to Target on assoc.id = id`
38
+
39
+ ### Changed
40
+
41
+ - to.edm(x):
42
+ + perform inbound qualification and spec violation checks as well as most/feasible EDM preprocessing steps
43
+ on requested services only.
44
+ + Open up `@odata { Type, MaxLength, Precision, Scale, SRID }` annotation.
45
+ The annotations behavior is defined as follows:
46
+ + The element/parameter must have a scalar CDS type. The annotation is not applied on named types
47
+ (With the V2 exception where derived type chains terminating in a scalar type are resolved).
48
+ + The value of `@odata.Type` must be a valid `EDM` type for the rendered protocol version.
49
+ + If `@odata.Type` can be applied, all canonic type facets (`MaxLength`, `Precision`, `Scale`, `SRID`) are
50
+ removed from the Edm Node and the new facets `@odata { MaxLength, Precision, Scale, SRID }` are applied.
51
+ Non Edm type conformant facets are ignored (eg. `@odata { Type: 'Edm.Decimal', MaxLength: 10, SRID: 0 }`).
52
+ + Type facet values are not evaluated.
53
+ + V2: Propagate `@Core.MediaType` annotation from stream element to entity type if not set.
54
+ - to.edm: Render constant expressions in short notation.
55
+ - Update OData Vocabularies: 'Common', 'Graph', 'Validation'.
56
+
57
+ ### Fixed
58
+
59
+ - to.cdl:
60
+ + Annotations of elements of action `returns` are now rendered as `annotate` statements.
61
+ + Annotations on columns (query sub-elements) were not always rendered.
62
+ + Doc comments on bound actions were rendered twice.
63
+ + Unapplied annotations for action parameters were not rendered.
64
+ + Unions and joins are correctly put into parentheses.
65
+ + Add parentheses around certain expressions in function bodies that require it, such as `fct((1=1))`.
66
+ - to.edm(x):
67
+ + Fix a bug in top level and derived type `items` exposure leading to undefined type rendering.
68
+ + Fix a naming bug in type exposure leading to false reuse types, disguising invididual type
69
+ modifications (such as annotations, (auto-)redirections, element extensions).
70
+ + Ignore `@Aggregation.default`.
71
+ + Consolidate message texts and formatting.
72
+ + Fix navigation property binding in cross service rendering mode.
73
+ + Remove partner attribute in proxy/cross service navigations.
74
+ - Core engine (function `compile`):
75
+ + Annotations for new columns inside `extend projection` blocks were not used.
76
+ + Extending an unknown select item resulted in a crash.
77
+ + Extending a context/service with columns now correctly emits an error.
78
+ + Unmanaged `redirected to` in queries did not check whether the source is an association.
79
+ - parseCdl: `extend <art> with enum {...}` incorrectly threw a compiler error.
80
+ - API: `compile()` used a synchronous call `fs.realpathSync()` on the input filename array.
81
+ Now the asynchronous `fs.realpath()` is used.
82
+ - On-conditions in localized convenience views may be incorrectly rewritten if an element
83
+ has the same as a localized entity.
84
+ - to.sql/hdi/hdbcds:
85
+ + No referential constraint is generated for an association if its parent
86
+ or target entity are annotated with `@cds.persistence.exists: true`.
87
+ + Fix rendering of virtual elements in subqueries
88
+ + Correctly process subqueries in JOINs
89
+ - to.sql/hdi: Queries with `UNION`, `INTERSECT` and similar in expressions are now enclosed in parentheses.
90
+
91
+ ## Version 2.14.0 - 2022-04-08
92
+
93
+ ### Added
94
+
95
+ - cdsc:
96
+ + `--quiet` can now be used to suppress compiler output, including messages.
97
+ + `--options <file.json>` can be used to load compiler options. A JSON file is expected. Is compatible to CDS `package.json`
98
+ and `.cdsrc.json` by first looking for `cdsc` key in `cds`, then for a `cdsc` key and otherwise uses the full JSON file.
99
+ + `--[error|warn|info|debug] id1,id2` can be used to reclassify specific messages.
100
+ - Add OData Vocabularies: 'DataIntegration', 'JSON'.
101
+
102
+ ### Changed
103
+
104
+ - Update OData Vocabularies: 'UI'.
105
+
106
+ ### Fixed
107
+
108
+ - to.cdl:
109
+ + Delimited identifiers as the last elements of arrays in annotation values are now
110
+ rendered with spaces in between, to avoid accidentally escaping `]`.
111
+ + Identifiers in includes and redirection targets were not quoted if they are reserved keywords.
112
+ - to.edm(x): Correctly rewrite `@Capabilities.ReadRestrictions.ReadByKeyRestrictions` into
113
+ `@Capabilities.NavigationPropertyRestriction` in containment mode.
114
+
115
+ ## Version 2.13.8 - 2022-03-29
116
+
117
+ ### Fixed
118
+
119
+ - to.hdbcds/hdi/sql: Correctly handle `localized` in conjunction with `@cds.persistence.exists` and `@cds.persistence.skip`
120
+
121
+ ## Version 2.13.6 - 2022-03-25
122
+
123
+ ### Fixed
124
+
125
+ - to.hdbcds/hdi/sql: Correctly handle `localized` in conjunction with `@cds.persistence.exists`
126
+
127
+ ## Version 2.13.4 - 2022-03-22
128
+
129
+ No changes compared to Version 2.13.0; fixes latest NPM tag
130
+
131
+ ## Version 2.13.2 - 2022-03-22
132
+
133
+ No changes compared to Version 2.13.0; fixes latest NPM tag
134
+
135
+ ## Version 2.13.0 - 2022-03-22
136
+
137
+ ### Added
138
+
139
+ - CDL syntax:
140
+ + Allow to `extend E:elem` and `annotate E:elem` instead of having to write deeply nested statements.
141
+ + Enable `default` values as part of scalar type definitions.
142
+ + The following `extend` syntax variants are now possible:
143
+ ```cds
144
+ extend … with elements { … }
145
+ extend … with definitions { … }
146
+ extend … with columns { … }
147
+ extend … with enum { … }
148
+ extend … with actions { … }
149
+ ```
150
+ This syntax expresses _how_ an artifact is extended instead of _what_ is extended.
151
+ + Using `ORDER BY` in generic functions such as SAP HANA's `first_value` is now possible.
152
+ - Make API function `compileSources` accept CSN objects as file content
153
+ - to.edm(x): Annotate view parameters with `@sap.parameter: mandatory` (V2) and `@Common.FieldControl: #Mandatory` (V4).
154
+ - to.sql/hdi/hdbcds: Introduce the annotations `@sql.prepend` and `@sql.append` that allow inserting user-written SQL
155
+ snippets into the compiler generated content. Changes in annotations `@sql.prepend` and `@sql.append` are now reflected
156
+ in the output of `to.hdi.migration`. This enables CDS Build to produce `.hdbmigrationtable` files translating such model
157
+ changes into schema changes.
158
+ - API: Lists of keywords for various backends are available as `to.<backend>[.<config>].keywords`, e.g. `to.sql.sqlite.keywords`.
159
+ - for.odata/to.edm(x): The draft composition hull is now also taking into account compositions in subelements.
160
+
161
+ ### Changed
162
+
163
+ - In query entities inside services, only auto-redirect associations and compositions
164
+ in the main query of the entity.
165
+ - An element now inherits the property `notNull` from its query source (as
166
+ before) or its type (like it does for most other properties);
167
+ `notNull` is then not further propagated to its sub elements anymore.
168
+ - A structure element inherits the property `virtual` from its query source (as
169
+ before), but does not further propagate `virtual` to its sub elements
170
+ (semantically of course, but the CSN is not cluttered with it);
171
+ there is a new warning if a previously `virtual` query entity
172
+ element is now considered to be non-virtual.
173
+ - Do not propagate annotation value `null`.
174
+ The value `null` of an annotation (and `doc`) is used to stop the inheritance
175
+ of an annotation value. This means than other than that, a value `null` should
176
+ not be handled differently to not having set that annotation.
177
+ - In the effective CSN, the structure type is only expanded if something has changed
178
+ for associations: the `target` (`keys` does not change if the `target` does not change)
179
+ unmanaged associations as sub elements are not supported anyway.
180
+ - In the effective CSN, “simple” type properties like `length`, `precision`,
181
+ `scale` and `srid` are propagated even for a propagation via type.
182
+ - Update OData Vocabularies: 'Capabilities', 'Common', 'Core', 'UI'.
183
+ - to.sql:
184
+ + For SQL dialect `hana` referential constraints are now appended
185
+ as `ALTER TABLE ADD CONSTRAINT` clause to the end of `schema.sql`.
186
+ With option `constraintsInCreateTable` constraints are rendered into the
187
+ `CREATE TABLE` statement.
188
+ + Referential constraint names are now prefixed with `c__`.
189
+
190
+ ### Fixed
191
+
192
+ - Properly resolve references inside anonymous aspects:
193
+ + references starting with `$self.` made the compiler dump.
194
+ + a simple `$self` did not always work as expected (it represents the entity created via the anonymous aspect).
195
+ + other references inside deeply nested anonymous aspects induced a compilation error.
196
+ - compiler: `()` inside `ORDER BY` clause was not correctly set.
197
+ - parse.cdl: References in `ORDER BY` and filters are now correctly resolved.
198
+ - Issue error when trying to introduce managed compositions of aspects in `mixin`s
199
+ - Issue error in all cases for type references to unmanaged associations.
200
+ - Avoid dump when extending an illegal definition with a name starting with `cds.`.
201
+ - to.sql/to.cdl/to.hdbcds/to.hdi: Render `cast()` inside `ORDER BY`, `GROUP BY` and `HAVING` properly.
202
+ - to.sql/hdi/hdbcds:
203
+ + `$self` was incorrectly treated as a structured path step.
204
+ + Correctly handle table alias in on-condition of mixin in `exists` expansion.
205
+ + Correctly handle table `$self` references to aliased fields in on-condition of mixin association
206
+ during `exists` expansion.
207
+ - to.edm: Don't escape `&` as `&amp;`.
208
+ - to.edmx: Escaping compliant to XML specification:
209
+ + `&` and `<` are always escaped.
210
+ + `>` is not escaped, unless it appears in text values as `]]>`.
211
+ + `"` is escaped in attribute values only.
212
+ + Control characters are always escaped.
213
+ - Ellipsis (`...`) in annotations in different layers but without base annotation now produces an error.
214
+ The old but incorrect behavior can be re-enabled with option `anno-unexpected-ellipsis-layers`.
215
+
10
216
  ## Version 2.12.0 - 2022-01-25
11
217
 
12
218
  ### Added
@@ -18,16 +224,16 @@ The compiler behavior concerning `beta` features can change at any time without
18
224
  for syntax highlighting, similar to markdown. In difference to the former, text blocks require the
19
225
  opening and closing backticks to be on separate lines.
20
226
  Example:
227
+ ````
228
+ @annotation: `Multi
229
+ line\u{0020}strings`
21
230
 
22
- @annotation: `Multi
23
- line\u{0020}strings`
24
-
25
- @textblock: ```xml
26
- <summary>
27
- <detail>The root tag has no indentation in this example</detail>
28
- </summary>
29
- ```
30
- ...
231
+ @textblock: ```xml
232
+ <summary>
233
+ <detail>The root tag has no indentation in this example</detail>
234
+ </summary>
235
+ ```
236
+ ````
31
237
 
32
238
  - Enhance the ellipsis operator `...` for array annotations by an `up to ‹val›`:
33
239
  only values in the array of the base annotation up to (including) the first match
@@ -38,12 +244,12 @@ The compiler behavior concerning `beta` features can change at any time without
38
244
  values in `‹val›` are equal to the corresponding property value in the array value;
39
245
  it is not necessary to specify all properties of the array value items in `‹val›`.
40
246
  Example
41
-
42
- @Anno: [{name: one, val: 1}, {name: two, val: 2}, {name: four, val: 4}]
43
- type T: Integer;
44
- @Anno: [{name: zero, val: 0}, ... up to {name: two}, {name: three, val: 3}, ...]
45
- annotate T;
46
-
247
+ ```
248
+ @Anno: [{name: one, val: 1}, {name: two, val: 2}, {name: four, val: 4}]
249
+ type T: Integer;
250
+ @Anno: [{name: zero, val: 0}, ... up to {name: two}, {name: three, val: 3}, ...]
251
+ annotate T;
252
+ ```
47
253
  - for.odata: Support `@cds.on {update|insert}` as replacement for deprecated `@odata.on { update|insert }` to
48
254
  set `@Core.Computed`.
49
255
 
package/bin/cdsc.js CHANGED
@@ -44,6 +44,18 @@ class ProcessExitError extends Error {
44
44
  }
45
45
  }
46
46
 
47
+ try {
48
+ cdsc_main();
49
+ }
50
+ catch (err) {
51
+ // This whole try/catch is only here because process.exit does not work in combination with
52
+ // stdout/err - see comment at ProcessExitError
53
+ if (err instanceof ProcessExitError)
54
+ process.exitCode = err.exitCode;
55
+ else
56
+ throw err;
57
+ }
58
+
47
59
  function remapCmdOptions(options, cmdOptions) {
48
60
  if (!cmdOptions)
49
61
  return options;
@@ -73,6 +85,9 @@ function remapCmdOptions(options, cmdOptions) {
73
85
  options.variableReplacements.$user = {};
74
86
  options.variableReplacements.$user.locale = value;
75
87
  break;
88
+ case 'serviceNames':
89
+ options.serviceNames = value.split(',');
90
+ break;
76
91
  default:
77
92
  options[key] = value;
78
93
  }
@@ -80,8 +95,9 @@ function remapCmdOptions(options, cmdOptions) {
80
95
  return options;
81
96
  }
82
97
 
83
- // Parse the command line and translate it into options
84
- try {
98
+ function cdsc_main() {
99
+ // Parse the command line and translate it into options
100
+
85
101
  const cmdLine = optionProcessor.processCmdLine(process.argv);
86
102
  // Deal with '--version' explicitly
87
103
  if (cmdLine.options.version) {
@@ -115,6 +131,11 @@ try {
115
131
  displayUsage(cmdLine.errors, optionProcessor.helpText, 2);
116
132
  }
117
133
 
134
+ if (cmdLine.options.options) {
135
+ if (!loadOptionsFromJson(cmdLine))
136
+ return;
137
+ }
138
+
118
139
  // Default warning level is 2 (info)
119
140
  // FIXME: Is that not set anywhere in the API?
120
141
  if (!cmdLine.options.warning)
@@ -125,11 +146,7 @@ try {
125
146
  cmdLine.options.out = '-';
126
147
 
127
148
  // --cds-home <dir>: modules starting with '@sap/cds/' are searched in <dir>
128
- if (cmdLine.options.cdsHome) {
129
- if (!global.cds)
130
- global.cds = {};
131
- global.cds.home = cmdLine.options.cdsHome;
132
- }
149
+ // -> cmdLine.options.cdsHome is passed down to moduleResolve
133
150
 
134
151
  // Set default command if required
135
152
  cmdLine.command = cmdLine.command || 'toCsn';
@@ -147,8 +164,8 @@ try {
147
164
  if (cmdLine.options.directBackend)
148
165
  validateDirectBackendOption(cmdLine.command, cmdLine.options, cmdLine.args);
149
166
 
150
-
151
- if (cmdLine.options.beta) {
167
+ // If set through CLI (and not options file), `beta` is a string and needs processing.
168
+ if (cmdLine.options.beta && typeof cmdLine.options.beta === 'string') {
152
169
  const features = cmdLine.options.beta.split(',');
153
170
  cmdLine.options.beta = {};
154
171
  features.forEach((val) => {
@@ -156,43 +173,32 @@ try {
156
173
  });
157
174
  }
158
175
 
176
+ const to = cmdLine.options.toSql ? 'toSql' : 'toHana';
159
177
  // remap string values for `assertIntegrity` option to boolean
160
- if (cmdLine.options.assertIntegrity &&
161
- cmdLine.options.assertIntegrity === 'true' ||
162
- cmdLine.options.assertIntegrity === 'false'
163
- )
164
- cmdLine.options.assertIntegrity = cmdLine.options.assertIntegrity === 'true';
165
-
166
- // remap string values for `constraintsAsAlter` option to boolean
167
- if (cmdLine.options.constraintsAsAlter &&
168
- cmdLine.options.constraintsAsAlter === 'true' ||
169
- cmdLine.options.constraintsAsAlter === 'false'
178
+ if (cmdLine.options[to] && cmdLine.options[to].assertIntegrity &&
179
+ (cmdLine.options[to].assertIntegrity === 'true' ||
180
+ cmdLine.options[to].assertIntegrity === 'false')
170
181
  )
171
- cmdLine.options.constraintsAsAlter = cmdLine.options.constraintsAsAlter === 'true';
172
-
182
+ cmdLine.options[to].assertIntegrity = cmdLine.options[to].assertIntegrity === 'true';
173
183
 
174
184
  // Enable all beta-flags if betaMode is set to true
175
185
  if (cmdLine.options.betaMode)
176
186
  cmdLine.options.beta = availableBetaFlags;
177
187
 
178
- if (cmdLine.options.deprecated) {
188
+ // If set through CLI (and not options file), `deprecated` is a string and needs processing.
189
+ if (cmdLine.options.deprecated && typeof cmdLine.options.deprecated === 'string') {
179
190
  const features = cmdLine.options.deprecated.split(',');
180
191
  cmdLine.options.deprecated = {};
181
192
  features.forEach((val) => {
182
193
  cmdLine.options.deprecated[val] = true;
183
194
  });
184
195
  }
196
+
197
+ parseSeverityOptions(cmdLine);
198
+
185
199
  // Do the work for the selected command
186
200
  executeCommandLine(cmdLine.command, cmdLine.options, cmdLine.args);
187
201
  }
188
- catch (err) {
189
- // This whole try/catch is only here because process.exit does not work in combination with
190
- // stdout/err - see comment at ProcessExitError
191
- if (err instanceof ProcessExitError)
192
- process.exitCode = err.exitCode;
193
- else
194
- throw err;
195
- }
196
202
 
197
203
  /**
198
204
  * `--direct-backend` can only be used with certain backends and with certain files.
@@ -238,10 +244,10 @@ function displayUsage(error, helpText, code) {
238
244
  function executeCommandLine(command, options, args) {
239
245
  const normalizeFilename = options.testMode && process.platform === 'win32';
240
246
  const messageLevels = {
241
- Error: 0, Warning: 1, Info: 2, None: 3,
247
+ Error: 0, Warning: 1, Info: 2, Debug: 3,
242
248
  };
243
249
  // All messages are put into the message array, even those which should not
244
- // been displayed (severity 'None')
250
+ // been displayed (severity 'Debug')
245
251
 
246
252
  // Create output directory if necessary
247
253
  if (options.out && options.out !== '-' && !fs.existsSync(options.out))
@@ -337,17 +343,18 @@ function executeCommandLine(command, options, args) {
337
343
  options.toOdata.odataContainment = true;
338
344
  }
339
345
  const csn = options.directBackend ? model : compactModel(model, options);
340
- const odataCsn = main.for.odata(csn, remapCmdOptions(options, options.toOdata));
346
+ const odataOptions = remapCmdOptions(options, options.toOdata);
341
347
  if (options.toOdata && options.toOdata.csn) {
348
+ const odataCsn = main.for.odata(csn, odataOptions);
342
349
  displayNamedCsn(odataCsn, 'odata_csn');
343
350
  }
344
351
  else if (options.toOdata && options.toOdata.json) {
345
- const result = main.to.edm.all(odataCsn, options);
352
+ const result = main.to.edm.all(csn, odataOptions);
346
353
  for (const serviceName in result)
347
354
  writeToFileOrDisplay(options.out, `${serviceName}.json`, result[serviceName]);
348
355
  }
349
356
  else {
350
- const result = main.to.edmx.all(odataCsn, options);
357
+ const result = main.to.edmx.all(csn, odataOptions);
351
358
  for (const serviceName in result)
352
359
  writeToFileOrDisplay(options.out, `${serviceName}.xml`, result[serviceName]);
353
360
  }
@@ -452,10 +459,10 @@ function executeCommandLine(command, options, args) {
452
459
  * Print the model's messages to stderr in a human readable way.
453
460
  *
454
461
  * @param {CSN.Model | XSN.Model} model
455
- * @param {CSN.Message[]} messages
462
+ * @param {CompileMessage[]} messages
456
463
  */
457
464
  function displayMessages( model, messages = options.messages ) {
458
- if (!Array.isArray(messages))
465
+ if (!Array.isArray(messages) || options.quiet)
459
466
  return model;
460
467
 
461
468
  const log = console.error;
@@ -483,7 +490,6 @@ function executeCommandLine(command, options, args) {
483
490
  hasAtLeastOneExplanation = hasAtLeastOneExplanation || main.hasMessageExplanation(msg.messageId);
484
491
  const name = msg.location && msg.location.file;
485
492
  const fullFilePath = name ? path.resolve('', name) : undefined;
486
- const context = fullFilePath ? sourceLines(fullFilePath) : [];
487
493
  log(main.messageStringMultiline(msg, {
488
494
  normalizeFilename,
489
495
  noMessageId: !options.showMessageId,
@@ -491,8 +497,12 @@ function executeCommandLine(command, options, args) {
491
497
  hintExplanation: true,
492
498
  color: options.color,
493
499
  }));
494
- if (context)
500
+ if (fullFilePath && msg.location.col) {
501
+ // A message context only makes sense, if we have at least a medium precision,
502
+ // i.e. line and column for start position.
503
+ const context = sourceLines(fullFilePath);
495
504
  log(main.messageContext(context, msg, { color: options.color }));
505
+ }
496
506
  log(); // newline
497
507
  });
498
508
  if (options.showMessageId && hasAtLeastOneExplanation)
@@ -557,8 +567,15 @@ function executeCommandLine(command, options, args) {
557
567
  content = JSON.stringify(content, null, 2);
558
568
 
559
569
  if (dir === '-') {
560
- if (!omitHeadline)
561
- process.stdout.write(`// ------------------- ${fileName} -------------------\n`);
570
+ if (options.quiet)
571
+ return;
572
+ if (!omitHeadline) {
573
+ const sqlTypes = {
574
+ sql: true, hdbconstraint: true, hdbtable: true, hdbview: true,
575
+ };
576
+ const commentStarter = fileName.split('.').pop() in sqlTypes ? '--$' : '//';
577
+ process.stdout.write(`${commentStarter} ------------------- ${fileName} -------------------\n`);
578
+ }
562
579
 
563
580
  process.stdout.write(`${content}\n`);
564
581
  if (!omitHeadline)
@@ -569,15 +586,73 @@ function executeCommandLine(command, options, args) {
569
586
  fs.writeFileSync(path.join(dir, fileName), content);
570
587
  }
571
588
  }
589
+ }
590
+
591
+ function loadOptionsFromJson(cmdLine) {
592
+ try {
593
+ let opt = JSON.parse(fs.readFileSync(cmdLine.options.options, 'utf-8'));
594
+ if (opt.cds)
595
+ opt = opt.cds;
596
+ if (opt.cdsc)
597
+ opt = opt.cdsc;
598
+ Object.assign(cmdLine.options, opt);
599
+ return true;
600
+ }
601
+ catch (e) {
602
+ catchErrors(e);
603
+ return false;
604
+ }
605
+ }
572
606
 
573
- function catchErrors(err) {
574
- // @ts-ignore
575
- if (err instanceof Error && err.hasBeenReported)
576
- return;
577
- console.error( '' );
578
- console.error( 'INTERNAL ERROR:' );
579
- console.error( util.inspect(err, false, null) );
580
- console.error( '' );
581
- process.exitCode = 70;
607
+ function catchErrors(err) {
608
+ // @ts-ignore
609
+ if (err instanceof Error && err.hasBeenReported)
610
+ return;
611
+ console.error( '' );
612
+ console.error( 'INTERNAL ERROR:' );
613
+ console.error( util.inspect(err, false, null) );
614
+ console.error( '' );
615
+ process.exitCode = 70;
616
+ }
617
+
618
+ /**
619
+ * Parses the options `--error` and similar.
620
+ * Sets the dictionary `severities` on the given options.
621
+ *
622
+ * @param {object} options
623
+ */
624
+ function parseSeverityOptions({ options }) {
625
+ if (!options.severities)
626
+ options.severities = Object.create(null);
627
+
628
+ const severityMap = {
629
+ error: 'Error',
630
+ warn: 'Warning',
631
+ info: 'Info',
632
+ debug: 'Debug',
633
+ };
634
+
635
+ // Note: We use a for loop to ensure that the order of the options on the command line is respected, i.e.
636
+ // `--warn id --error id` would lead to `id` being reclassified as an error and not a warning.
637
+ for (const key in options) {
638
+ switch (key) {
639
+ case 'error':
640
+ case 'warn':
641
+ case 'info':
642
+ case 'debug':
643
+ parseSeverityOption(options[key], severityMap[key]);
644
+ break;
645
+ default:
646
+ break;
647
+ }
648
+ }
649
+
650
+ function parseSeverityOption(list, severity) {
651
+ const ids = list.split(',');
652
+ for (let id of ids) {
653
+ id = id.trim();
654
+ if (id)
655
+ options.severities[id] = severity;
656
+ }
582
657
  }
583
658
  }
package/bin/cdsse.js CHANGED
@@ -144,8 +144,8 @@ function lint( err, buf ) {
144
144
  }
145
145
  }
146
146
 
147
- function tokensAt( buf, offset, col, symbol ) {
148
- const src = `${buf.substring( 0, offset )}≠${buf.substring( offset )}`;
147
+ function tokensAt( buf, _offset, col, symbol ) {
148
+ const src = `${buf.substring( 0, _offset )}≠${buf.substring( _offset )}`;
149
149
  const et = messageAt( compiler.parseX( src, frel, { messages: [] } ), 'expectedTokens', col ) || [];
150
150
  for (const n of et) {
151
151
  if (typeof symbol === 'string') {
@@ -8,23 +8,30 @@ 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 2.XX.YY
12
+
13
+ ### Removed `assocsWithParams`
14
+
15
+ Instead, of using the beta flag `assocsWithParams`, you can change the severity of the messages
16
+ `def-unexpected-paramview-assoc` and `def-unexpected-calcview-assoc`.
17
+
11
18
  ## Version 2.12.0 - 2022-01-25
12
19
 
13
20
  ### Added `sqlSnippets`
14
21
 
15
22
  - to.sql/hdi/hdbcds: Introduce the annotations `@sql.prepend` and `@sql.append` that allow inserting user-written SQL snippets into the compiler generated content.
16
23
 
17
- ## Version 2.11.0
24
+ ## Version 2.11.0 - 2021-12-02
18
25
 
19
26
  ### Removed `foreignKeyConstraints`
20
27
 
21
- ## Version 2.10.4
28
+ ## Version 2.10.4 - 2021-11-05
22
29
 
23
30
  ### Fixed `nestedProjections`
24
31
 
25
32
  - to.sql/hdi/hdbcds: Correctly handle a `*` at the not-first place in the query
26
33
 
27
- ## Version 2.6.0
34
+ ## Version 2.6.0 - 2021-08-23
28
35
 
29
36
  ### Removed `pretransformedCSN`
30
37
 
@@ -48,7 +55,7 @@ This is now the default - see CHANGELOG entry for 2.6.0
48
55
  - Composition of one w/o backlink will result in a constraint in
49
56
  the entity where the composition is defined
50
57
 
51
- ## Version 2.4.4
58
+ ## Version 2.4.4 - 2021-07-02
52
59
 
53
60
  ### Added `nestedProjections`
54
61
 
@@ -59,7 +66,7 @@ This is now the default - see CHANGELOG entry for 2.6.0
59
66
  - _Some checks are missing and will be added! Minor changes might occur._
60
67
  - **The SQL backends might not work properly yet if nested projections are used!**
61
68
 
62
- ## Version 2.4.2
69
+ ## Version 2.4.2 - 2021-07-01
63
70
 
64
71
  ### Added `keylessManagedAssoc`
65
72
 
@@ -71,7 +78,7 @@ This is now the default - see CHANGELOG entry for 2.6.0
71
78
  Consequently, these associations are not added to the `WITH ASSOCIATIONS` clause or forwarded to HANA CDS.
72
79
  Managed Associations without foreign keys must be enabled with `--beta: keylessManagedAssoc`
73
80
 
74
- ## Version 2.4.0
81
+ ## Version 2.4.0 - 2021-06-28
75
82
 
76
83
  ### Changed `foreignKeyConstraints`
77
84