@sap/cds-compiler 2.10.4 → 2.12.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.
Files changed (103) hide show
  1. package/CHANGELOG.md +136 -0
  2. package/bin/.eslintrc.json +1 -2
  3. package/bin/cds_update_identifiers.js +10 -8
  4. package/bin/cdsc.js +58 -35
  5. package/bin/cdsse.js +1 -0
  6. package/bin/cdsv2m.js +3 -2
  7. package/doc/CHANGELOG_ARCHIVE.md +1 -1
  8. package/doc/CHANGELOG_BETA.md +16 -0
  9. package/lib/api/.eslintrc.json +2 -0
  10. package/lib/api/main.js +10 -36
  11. package/lib/api/options.js +17 -8
  12. package/lib/api/validate.js +30 -3
  13. package/lib/backends.js +12 -13
  14. package/lib/base/dictionaries.js +2 -1
  15. package/lib/base/keywords.js +3 -2
  16. package/lib/base/message-registry.js +64 -11
  17. package/lib/base/messages.js +38 -18
  18. package/lib/base/model.js +6 -4
  19. package/lib/base/optionProcessorHelper.js +148 -86
  20. package/lib/checks/.eslintrc.json +2 -0
  21. package/lib/checks/actionsFunctions.js +2 -1
  22. package/lib/checks/emptyOrOnlyVirtual.js +2 -2
  23. package/lib/checks/foreignKeys.js +4 -4
  24. package/lib/checks/managedInType.js +4 -4
  25. package/lib/checks/queryNoDbArtifacts.js +1 -3
  26. package/lib/checks/selectItems.js +4 -0
  27. package/lib/checks/sql-snippets.js +93 -0
  28. package/lib/checks/unknownMagic.js +6 -3
  29. package/lib/checks/validator.js +8 -0
  30. package/lib/compiler/assert-consistency.js +14 -5
  31. package/lib/compiler/base.js +64 -0
  32. package/lib/compiler/builtins.js +62 -16
  33. package/lib/compiler/checks.js +34 -10
  34. package/lib/compiler/definer.js +91 -112
  35. package/lib/compiler/index.js +30 -30
  36. package/lib/compiler/propagator.js +8 -4
  37. package/lib/compiler/resolver.js +279 -63
  38. package/lib/compiler/shared.js +65 -230
  39. package/lib/compiler/utils.js +191 -0
  40. package/lib/edm/annotations/genericTranslation.js +35 -18
  41. package/lib/edm/annotations/preprocessAnnotations.js +1 -1
  42. package/lib/edm/csn2edm.js +4 -3
  43. package/lib/edm/edm.js +8 -8
  44. package/lib/edm/edmPreprocessor.js +61 -59
  45. package/lib/edm/edmUtils.js +14 -15
  46. package/lib/gen/Dictionary.json +82 -40
  47. package/lib/gen/language.checksum +1 -1
  48. package/lib/gen/language.interp +19 -1
  49. package/lib/gen/language.tokens +80 -73
  50. package/lib/gen/languageLexer.interp +27 -1
  51. package/lib/gen/languageLexer.js +925 -826
  52. package/lib/gen/languageLexer.tokens +72 -65
  53. package/lib/gen/languageParser.js +4817 -4102
  54. package/lib/json/from-csn.js +57 -26
  55. package/lib/json/to-csn.js +244 -51
  56. package/lib/language/antlrParser.js +12 -1
  57. package/lib/language/docCommentParser.js +1 -1
  58. package/lib/language/errorStrategy.js +26 -8
  59. package/lib/language/genericAntlrParser.js +106 -30
  60. package/lib/language/language.g4 +200 -70
  61. package/lib/language/multiLineStringParser.js +536 -0
  62. package/lib/main.d.ts +220 -21
  63. package/lib/main.js +6 -3
  64. package/lib/model/api.js +2 -2
  65. package/lib/model/csnRefs.js +218 -86
  66. package/lib/model/csnUtils.js +99 -178
  67. package/lib/model/enrichCsn.js +84 -43
  68. package/lib/model/revealInternalProperties.js +25 -8
  69. package/lib/model/sortViews.js +8 -1
  70. package/lib/modelCompare/compare.js +2 -1
  71. package/lib/optionProcessor.js +33 -18
  72. package/lib/render/.eslintrc.json +1 -2
  73. package/lib/render/DuplicateChecker.js +2 -2
  74. package/lib/render/manageConstraints.js +1 -1
  75. package/lib/render/toCdl.js +202 -82
  76. package/lib/render/toHdbcds.js +194 -135
  77. package/lib/render/toRename.js +7 -10
  78. package/lib/render/toSql.js +91 -51
  79. package/lib/render/utils/common.js +24 -5
  80. package/lib/render/utils/sql.js +6 -4
  81. package/lib/transform/braceExpression.js +4 -2
  82. package/lib/transform/db/applyTransformations.js +189 -0
  83. package/lib/transform/db/associations.js +389 -0
  84. package/lib/transform/db/cdsPersistence.js +150 -0
  85. package/lib/transform/db/constraints.js +275 -119
  86. package/lib/transform/db/draft.js +6 -4
  87. package/lib/transform/db/expansion.js +10 -9
  88. package/lib/transform/db/flattening.js +23 -8
  89. package/lib/transform/db/temporal.js +236 -0
  90. package/lib/transform/db/transformExists.js +106 -25
  91. package/lib/transform/db/views.js +485 -0
  92. package/lib/transform/forHanaNew.js +90 -1036
  93. package/lib/transform/forOdataNew.js +11 -3
  94. package/lib/transform/localized.js +5 -14
  95. package/lib/transform/odata/generateForeignKeyElements.js +2 -2
  96. package/lib/transform/transformUtilsNew.js +34 -20
  97. package/lib/transform/translateAssocsToJoins.js +15 -23
  98. package/lib/transform/universalCsnEnricher.js +217 -47
  99. package/lib/utils/file.js +13 -6
  100. package/lib/utils/term.js +65 -42
  101. package/lib/utils/timetrace.js +55 -27
  102. package/package.json +1 -1
  103. package/lib/transform/db/helpers.js +0 -58
package/CHANGELOG.md CHANGED
@@ -7,6 +7,142 @@
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 2.12.0 - 2022-01-25
11
+
12
+ ### Added
13
+
14
+ - CDL parser: You can now use multiline string literals and text blocks.
15
+ Use backticks (\`) for string literals that can span multiple lines and can use JavaScript-like escape
16
+ sequences such as `\u{0020}`. You can also use three backticks (\`\`\`) for strings (a.k.a. text blocks)
17
+ which are automatically indentation-stripped and can have an optional language identifier that is used
18
+ for syntax highlighting, similar to markdown. In difference to the former, text blocks require the
19
+ opening and closing backticks to be on separate lines.
20
+ Example:
21
+
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
+ ...
31
+
32
+ - Enhance the ellipsis operator `...` for array annotations by an `up to ‹val›`:
33
+ only values in the array of the base annotation up to (including) the first match
34
+ of the specified `‹val›` are included at the specified place in the final array value.
35
+ An array annotation can have more than on `... up to ‹val›` items and must also
36
+ have a pure `...` item after them.
37
+ A structured `‹val›` matches if the array item is also a structure and all property
38
+ values in `‹val›` are equal to the corresponding property value in the array value;
39
+ it is not necessary to specify all properties of the array value items in `‹val›`.
40
+ 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
+
47
+ - for.odata: Support `@cds.on {update|insert}` as replacement for deprecated `@odata.on { update|insert }` to
48
+ set `@Core.Computed`.
49
+
50
+ ### Changed
51
+
52
+ - Update OData Vocabularies 'Aggregation', 'Capabilities', 'Common', 'Core', PersonalData, 'Session', 'UI'
53
+
54
+ ### Fixed
55
+
56
+ - to.sql/hdi/hdbcds: With `exists`, ensure that the precedence of the existing association-on-conditions and where-conditions is kept by adding braces.
57
+ - to.sql/hdi: Window function suffixes are now properly rendered.
58
+ - to.sql: `$self` comparisons inside aspects are not checked and won't result in an error anymore.
59
+ - to.hdbcds:
60
+ + Correctly apply the "."-to-"_"-translation algorithm to artifacts that are marked with `@cds.persistence.exists`.
61
+ + Message with ID `anno-hidden-exists` (former `anno-unstable-hdbcds`) is now
62
+ only issued if the compiler generates a SAP HANA CDS artifact which would hide
63
+ a native database object from being resolved in a SAP HANA CDS `using … as …`.
64
+ - to.cdl: Annotation paths containing special characters such as spaces or `@` are now quoted, e.g. `@![some@annotation]`.
65
+ - compiler: A warning is emitted for elements of views with localized keys as the localized property is ignored for them.
66
+
67
+ ## Version 2.11.4 - 2021-12-21
68
+
69
+ ### Fixed
70
+
71
+ - CDL parser: in many situations, improve message when people use reserved keywords as identifier
72
+ - Improve error text and error location for ambiguous auto-redirection target
73
+ - to.sql/hdi/hdbcds:
74
+ + Correctly detect `exists` in projections
75
+ + Correctly handle elements starting with `$` in the on-condition of associations
76
+ + Correctly handle sub queries in an entity defined with `projection on`
77
+ + Correctly handle associations in sub queries in a `from` of a sub query
78
+ + foreign key constraints: respect @assert.integrity: false for compositions
79
+ - to.hdbcds: Correctly quote elements named `$self` and `$projection`
80
+ - to.cdl: `when` was added to the keyword list for smart quoting
81
+ - Compiler support for code completion for `$user` and `$session` now respect user
82
+ provided variables in `options.variableReplacements`.
83
+ - API: `deduplicateMessages()` no longer removes messages for `duplicate` artifact/annotation errors.
84
+ Prior to this version, only one of the duplicated artifacts had a message, leaving the user to
85
+ guess where the other duplicates were.
86
+
87
+
88
+ ## Version 2.11.2 - 2021-12-06
89
+
90
+ ### Fixed
91
+
92
+ - to.sql/hdi/hdbcds:
93
+ + No foreign key constraint will be rendered for managed `composition of one` if annotated with `@assert.integrity: false`
94
+ + Correctly handle managed associations with other managed associations as foreign keys in conjunction with `exists`
95
+
96
+ ## Version 2.11.0 - 2021-12-02
97
+
98
+ ### Added
99
+
100
+ - Option `defaultBinaryLength` to set a `length` type facet for all definitions with type `cds.Binary`. This option
101
+ overrides the default binary length in the database backends and is also used as `MaxLength` attribute in Odata.
102
+ - If doc-comments are ignored by the compiler, an info message is now emitted. A doc-comment is ignored,
103
+ if it can't be assigned to an artifact. For example for two subsequent doc-comments, the first doc-comment
104
+ is ignored. To suppress these info messages, explicitly set option `docComment` to `false`.
105
+ - `cdsc`:
106
+ + `cdsc explain list` can now be used to get a list of message IDs with explanation texts.
107
+ + `cdsc` now respects the environment variable `NO_COLOR`. If set, no ANSI escape codes will be used.
108
+ Can be overwritten by `cdsc --color always`.
109
+ - to.sql/hdi: Support SQL Window Functions
110
+ - to.sql/hdi/hdbcds:
111
+ + Support configuration of `$session` and `$user` via option `variableReplacements`.
112
+ + Restricted support for SQL foreign key constraints if option `assertIntegrityType` is set to `"DB"`.
113
+ The behavior of this feature might change in the future.
114
+
115
+ ### Changed
116
+
117
+ - Updated OData vocabularies 'Common' and 'UI'.
118
+ - to.sql/hdi/hdbcds: The default length of `cds.Binary` is set to `5000` similar to `cds.String`.
119
+
120
+ ### Removed
121
+
122
+ - to.hdbcds: Doc comments on view columns are not rendered anymore. Doc comments on string literals will make the deployment fail
123
+ as the SAP HANA CDS compiler concatenates the doc comment with the string literal. Besides that, doc comments on view columns
124
+ are not transported to the database by SAP HANA CDS.
125
+ - to.hdbcds/sql/hdi: Forbid associations in filters after `exists` (except for nested `exists`), as the final behavior is not yet specified.
126
+
127
+ ### Fixed
128
+
129
+ - CSN parser: doc-comment extensions are no longer ignored.
130
+ - Properly check for duplicate annotation definitions.
131
+ - Correctly apply annotations on inherited enum symbols.
132
+ - Correctly apply annotations on elements in an inherited structure array.
133
+ - Fix a bug in API `defaultStringLength` value evaluation.
134
+ - Fix crash if named arguments are used in a function that's inside a `CASE` statement.
135
+ - to.sql/hdi/hdbcds:
136
+ + Properly flatten ad-hoc defined elements in `returns` / `params` of `actions` and `functions`.
137
+ + Correctly handle `*` in non-first position.
138
+ + Correctly handle action return types
139
+ + Correctly handle mixin association named `$self`
140
+ - to.cdl: doc-comments are no longer rendered twice.
141
+ - to.edm(x):
142
+ + Fix a bug in V2/V4 partner ship calculation.
143
+ + Remove warning of unknown types for Open Types in `@Core.Dictionary`.
144
+ + An empty CSN no longer results in a JavaScript type error
145
+
10
146
  ## Version 2.10.4 - 2021-11-05
11
147
 
12
148
  ### Fixed
@@ -11,7 +11,6 @@
11
11
  "no-process-exit": "off",
12
12
  "camelcase": "off",
13
13
  "radix": "off",
14
- // should probably be on
15
- "no-shadow": "off"
14
+ "no-shadow": "warn"
16
15
  }
17
16
  }
@@ -24,37 +24,39 @@
24
24
  'use strict';
25
25
 
26
26
  const parseLanguage = require('../lib/language/antlrParser');
27
+ const { createMessageFunctions } = require('../lib/base/messages');
27
28
 
28
29
  const fs = require('fs');
29
30
  const path = require('path');
30
31
 
31
32
  const cliArgs = process.argv.slice(2);
32
- const filename = cliArgs[0];
33
+ const filepath = cliArgs[0];
33
34
 
34
35
  if (cliArgs.length !== 1)
35
36
  exitError(`Expected exactly one argument, ${cliArgs.length} given`);
36
37
 
37
- if (!filename)
38
- exitError('Expected non-empty filename as argument!');
38
+ if (!filepath)
39
+ exitError('Expected non-empty filepath as argument!');
39
40
 
40
41
  // Do not use allow-list approach.
41
42
  // There may be CDS files with other extensions than `.cds`.
42
- if (filename.endsWith('.csn') || filename.endsWith('.json'))
43
+ if (filepath.endsWith('.csn') || filepath.endsWith('.json'))
43
44
  exitError('Only CDS files can be passed! Found CSN file!');
44
45
 
45
- let source = fs.readFileSync(filename, 'utf-8');
46
- source = modernizeIdentifierStyle(source, filename);
47
- fs.writeFileSync(filename, source);
46
+ let sourceStr = fs.readFileSync(filepath, 'utf-8');
47
+ sourceStr = modernizeIdentifierStyle(sourceStr, filepath);
48
+ fs.writeFileSync(filepath, sourceStr);
48
49
  process.exit(0); // success
49
50
 
50
51
  // --------------------------------------------------------
51
52
 
52
53
  function modernizeIdentifierStyle(source, filename) {
53
54
  const options = { messages: [], attachTokens: true };
55
+ const messageFunctions = createMessageFunctions( options, 'parse', null );
54
56
 
55
57
  // parseLanguage does not throw on CompilationError, so
56
58
  // we do not need a try...catch block.
57
- const ast = parseLanguage(source, filename, options);
59
+ const ast = parseLanguage(source, filename, options, messageFunctions);
58
60
 
59
61
  // To avoid spam, only report errors.
60
62
  // Users should use the compiler to get all messages.
package/bin/cdsc.js CHANGED
@@ -26,8 +26,10 @@ const path = require('path');
26
26
  const { reveal } = require('../lib/model/revealInternalProperties');
27
27
  const enrichCsn = require('../lib/model/enrichCsn');
28
28
  const { optionProcessor } = require('../lib/optionProcessor');
29
- const { explainMessage, hasMessageExplanation, sortMessages } = require('../lib/base/messages');
30
- const term = require('../lib/utils/term');
29
+ const {
30
+ explainMessage, hasMessageExplanation, sortMessages, messageIdsWithExplanation,
31
+ } = require('../lib/base/messages');
32
+ const { term } = require('../lib/utils/term');
31
33
  const { splitLines } = require('../lib/utils/file');
32
34
  const { addLocalizationViews } = require('../lib/transform/localized');
33
35
  const { availableBetaFlags } = require('../lib/base/model');
@@ -52,9 +54,11 @@ function remapCmdOptions(options, cmdOptions) {
52
54
  options.sqlMapping = value;
53
55
  break;
54
56
  case 'user':
55
- if (!options.magicVars)
56
- options.magicVars = {};
57
- options.magicVars.user = value;
57
+ if (!options.variableReplacements)
58
+ options.variableReplacements = {};
59
+ if (!options.variableReplacements.$user)
60
+ options.variableReplacements.$user = {};
61
+ options.variableReplacements.$user.id = value;
58
62
  break;
59
63
  case 'dialect':
60
64
  options.sqlDialect = value;
@@ -63,9 +67,11 @@ function remapCmdOptions(options, cmdOptions) {
63
67
  options.odataVersion = value;
64
68
  break;
65
69
  case 'locale':
66
- if (!options.magicVars)
67
- options.magicVars = {};
68
- options.magicVars.locale = value;
70
+ if (!options.variableReplacements)
71
+ options.variableReplacements = {};
72
+ if (!options.variableReplacements.$user)
73
+ options.variableReplacements.$user = {};
74
+ options.variableReplacements.$user.locale = value;
69
75
  break;
70
76
  default:
71
77
  options[key] = value;
@@ -124,8 +130,6 @@ try {
124
130
  global.cds = {};
125
131
  global.cds.home = cmdLine.options.cdsHome;
126
132
  }
127
- // Default color mode is 'auto'
128
- term.useColor(cmdLine.options.color || 'auto');
129
133
 
130
134
  // Set default command if required
131
135
  cmdLine.command = cmdLine.command || 'toCsn';
@@ -137,10 +141,7 @@ try {
137
141
  if (cmdLine.command === 'parseCdl') {
138
142
  cmdLine.command = 'toCsn';
139
143
  cmdLine.options.parseCdl = true;
140
- if (cmdLine.args.files.length > 1) {
141
- const err = `'parseCdl' expects exactly one file! ${cmdLine.args.files.length} provided.`;
142
- displayUsage(err, optionProcessor.commands.parseCdl.helpText, 2);
143
- }
144
+ cmdLine.args.files = [ cmdLine.args.file ];
144
145
  }
145
146
 
146
147
  if (cmdLine.options.directBackend)
@@ -155,6 +156,21 @@ try {
155
156
  });
156
157
  }
157
158
 
159
+ // 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'
170
+ )
171
+ cmdLine.options.constraintsAsAlter = cmdLine.options.constraintsAsAlter === 'true';
172
+
173
+
158
174
  // Enable all beta-flags if betaMode is set to true
159
175
  if (cmdLine.options.betaMode)
160
176
  cmdLine.options.beta = availableBetaFlags;
@@ -211,7 +227,7 @@ function displayUsage(error, helpText, code) {
211
227
  out.write(`${helpText}\n`);
212
228
  if (error) {
213
229
  if (error instanceof Array)
214
- out.write(`${error.map(error => `cdsc: ERROR: ${error}`).join('\n')}\n`);
230
+ out.write(`${error.map(err => `cdsc: ERROR: ${err}`).join('\n')}\n`);
215
231
  else
216
232
  out.write(`cdsc: ERROR: ${error}\n`);
217
233
  }
@@ -231,6 +247,8 @@ function executeCommandLine(command, options, args) {
231
247
  if (options.out && options.out !== '-' && !fs.existsSync(options.out))
232
248
  fs.mkdirSync(options.out);
233
249
 
250
+ // Default color mode is 'auto'
251
+ const colorTerm = term(options.color || 'auto');
234
252
 
235
253
  // Add implementation functions corresponding to commands here
236
254
  const commands = {
@@ -283,11 +301,11 @@ function executeCommandLine(command, options, args) {
283
301
  // Return the original model (for chaining)
284
302
  function toCsn( model ) {
285
303
  if (options.directBackend) {
286
- displayNamedCsn(model, 'csn', options);
304
+ displayNamedCsn(model, 'csn');
287
305
  }
288
306
  else {
289
307
  // Result already provided by caller
290
- displayNamedXsn(model, 'csn', options);
308
+ displayNamedXsn(model, 'csn');
291
309
  }
292
310
  return model;
293
311
  }
@@ -298,7 +316,7 @@ function executeCommandLine(command, options, args) {
298
316
  const csn = options.directBackend ? model : compactModel(model, options);
299
317
 
300
318
  if (options.toHana && options.toHana.csn) {
301
- displayNamedCsn(for_hdbcds(csn, remapCmdOptions(options, options.toHana)), 'hana_csn', options);
319
+ displayNamedCsn(for_hdbcds(csn, remapCmdOptions(options, options.toHana)), 'hana_csn');
302
320
  }
303
321
  else {
304
322
  const hanaResult = main.to.hdbcds(csn, remapCmdOptions(options, options.toHana));
@@ -321,7 +339,7 @@ function executeCommandLine(command, options, args) {
321
339
  const csn = options.directBackend ? model : compactModel(model, options);
322
340
  const odataCsn = main.for.odata(csn, remapCmdOptions(options, options.toOdata));
323
341
  if (options.toOdata && options.toOdata.csn) {
324
- displayNamedCsn(odataCsn, 'odata_csn', options);
342
+ displayNamedCsn(odataCsn, 'odata_csn');
325
343
  }
326
344
  else if (options.toOdata && options.toOdata.json) {
327
345
  const result = main.to.edm.all(odataCsn, options);
@@ -374,7 +392,7 @@ function executeCommandLine(command, options, args) {
374
392
  const csn = options.directBackend ? model : compactModel(model, options);
375
393
  if (options.toSql && options.toSql.src === 'hdi') {
376
394
  if (options.toSql.csn) {
377
- displayNamedCsn(for_hdi(csn, remapCmdOptions(options, options.toSql)), 'hdi_csn', options);
395
+ displayNamedCsn(for_hdi(csn, remapCmdOptions(options, options.toSql)), 'hdi_csn');
378
396
  }
379
397
  else {
380
398
  const hdiResult = main.to.hdi(csn, remapCmdOptions(options, options.toSql));
@@ -383,7 +401,7 @@ function executeCommandLine(command, options, args) {
383
401
  }
384
402
  }
385
403
  else if (options.toSql && options.toSql.csn) {
386
- displayNamedCsn(for_sql(csn, remapCmdOptions(options, options.toSql)), 'sql_csn', options);
404
+ displayNamedCsn(for_sql(csn, remapCmdOptions(options, options.toSql)), 'sql_csn');
387
405
  }
388
406
  else {
389
407
  const sqlResult = main.to.sql(csn, remapCmdOptions(options, options.toSql));
@@ -393,14 +411,15 @@ function executeCommandLine(command, options, args) {
393
411
  }
394
412
 
395
413
  function explain() {
396
- if (args.length !== 1)
397
- displayUsage('Command \'explain\' expects exactly one message-id.', optionProcessor.commands.explain.helpText, 2);
414
+ if (args.messageId === 'list') {
415
+ console.log(messageIdsWithExplanation().join('\n'));
416
+ throw new ProcessExitError(0);
417
+ }
398
418
 
399
- const id = args.files[0];
400
- if (!hasMessageExplanation(id))
401
- console.error(`Message '${id}' does not have an explanation!`);
419
+ if (!hasMessageExplanation(args.messageId))
420
+ console.error(`Message '${args.messageId}' does not have an explanation!`);
402
421
  else
403
- console.log(explainMessage(id));
422
+ console.log(explainMessage(args.messageId));
404
423
  }
405
424
 
406
425
  // Display error messages in `err` resulting from a compilation. Also set
@@ -464,16 +483,20 @@ function executeCommandLine(command, options, args) {
464
483
  hasAtLeastOneExplanation = hasAtLeastOneExplanation || main.hasMessageExplanation(msg.messageId);
465
484
  const name = msg.location && msg.location.file;
466
485
  const fullFilePath = name ? path.resolve('', name) : undefined;
467
- const context = fullFilePath && sourceLines(fullFilePath);
486
+ const context = fullFilePath ? sourceLines(fullFilePath) : [];
468
487
  log(main.messageStringMultiline(msg, {
469
- normalizeFilename, noMessageId: !options.showMessageId, withLineSpacer: true, hintExplanation: true,
488
+ normalizeFilename,
489
+ noMessageId: !options.showMessageId,
490
+ withLineSpacer: true,
491
+ hintExplanation: true,
492
+ color: options.color,
470
493
  }));
471
494
  if (context)
472
- log(main.messageContext(context, msg));
495
+ log(main.messageContext(context, msg, { color: options.color }));
473
496
  log(); // newline
474
497
  });
475
498
  if (options.showMessageId && hasAtLeastOneExplanation)
476
- log(`${term.help('help')}: Messages marked with '…' have an explanation text. Use \`cdsc explain <message-id>\` for a more detailed error description.`);
499
+ log(`${colorTerm.help('help')}: Messages marked with '…' have an explanation text. Use \`cdsc explain <message-id>\` for a more detailed error description.`);
477
500
  }
478
501
  return model;
479
502
  }
@@ -482,7 +505,7 @@ function executeCommandLine(command, options, args) {
482
505
  // or display it to stdout if 'options.out' is '-'.
483
506
  // Depending on 'options.rawOutput', the model is either compacted to 'name.json' or
484
507
  // written in raw form to '<name>_raw.txt'.
485
- function displayNamedXsn(xsn, name, options) {
508
+ function displayNamedXsn(xsn, name) {
486
509
  if (options.rawOutput) {
487
510
  writeToFileOrDisplay(options.out, `${name}_raw.txt`, util.inspect(reveal(xsn, options.rawOutput), false, null), true);
488
511
  }
@@ -502,9 +525,8 @@ function executeCommandLine(command, options, args) {
502
525
  /**
503
526
  * @param {CSN.Model} csn
504
527
  * @param {string} name
505
- * @param {CSN.Options} options
506
528
  */
507
- function displayNamedCsn(csn, name, options) {
529
+ function displayNamedCsn(csn, name) {
508
530
  if (!csn) // only print CSN if it is set.
509
531
  return;
510
532
  if (options.internalMsg) {
@@ -549,10 +571,11 @@ function executeCommandLine(command, options, args) {
549
571
  }
550
572
 
551
573
  function catchErrors(err) {
574
+ // @ts-ignore
552
575
  if (err instanceof Error && err.hasBeenReported)
553
576
  return;
554
577
  console.error( '' );
555
- console.error( 'INTERNAL ERROR: %s', err );
578
+ console.error( 'INTERNAL ERROR:' );
556
579
  console.error( util.inspect(err, false, null) );
557
580
  console.error( '' );
558
581
  process.exitCode = 70;
package/bin/cdsse.js CHANGED
@@ -11,6 +11,7 @@
11
11
  // Planned are: gotoDefinition, highlight (for syntax highighting).
12
12
 
13
13
  /* eslint no-console:off */
14
+ // @ts-nocheck
14
15
 
15
16
  'use strict';
16
17
 
package/bin/cdsv2m.js CHANGED
@@ -34,10 +34,11 @@ function usage( err ) {
34
34
  function ria() {
35
35
  const annotates = Object.create( null );
36
36
  const msgs = options.messages.filter( m => m.messageId === 'redirected-implicitly-ambiguous' );
37
- // regex match on message text not for productive code!
37
+ // 'Choose via $(ANNO) one of $(SORTED_ARTS) as redirection target for $(TARGET) in … $(ART) otherwise'
38
+ // NOTE: regex match on message text not for productive code!
38
39
  for (const msgObj of msgs) {
39
40
  const matches = msgObj.message.match( /["“][^"”]+["”]/g );
40
- matches.slice(2).forEach( (name) => {
41
+ matches.slice( 1, -2 ).forEach( (name) => {
41
42
  annotates[name.slice( 1, -1 )] = true;
42
43
  } );
43
44
  }
@@ -1516,7 +1516,7 @@ Changes
1516
1516
  * Preserve the `key` properties of elements selected in a view (like we do in projections).
1517
1517
  * Improve the CSN representation for views.
1518
1518
  Represent the `where` and `on` condition of `select`s like other conditions.
1519
- * Project name in github is now `cdx/cds-compiler`.
1519
+ * Project name in github is now `cap/cds-compiler`.
1520
1520
 
1521
1521
  Features
1522
1522
  * Support `select *` in views.
@@ -8,6 +8,16 @@ 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.12.0 - 2022-01-25
12
+
13
+ ### Added `sqlSnippets`
14
+
15
+ - 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
+
17
+ ## Version 2.11.0
18
+
19
+ ### Removed `foreignKeyConstraints`
20
+
11
21
  ## Version 2.10.4
12
22
 
13
23
  ### Fixed `nestedProjections`
@@ -159,6 +169,12 @@ The association to join transformation treats foreign key accesses with priority
159
169
 
160
170
  Unique constraints are now generally available.
161
171
 
172
+ ## Version 1.33.0 - 2020-08-24
173
+
174
+ ### Added `hanaAssocRealCardinality`
175
+
176
+ Render JOIN cardinality in native HANA association if provided. If no cardinality has been specified.
177
+
162
178
  ## Version 1.32.0 - 2020-07-10
163
179
 
164
180
  ### Removed `aspectCompositions`
@@ -14,6 +14,8 @@
14
14
  "jsdoc"
15
15
  ],
16
16
  "rules": {
17
+ // Does not recognize TS types
18
+ "jsdoc/no-undefined-types": "off",
17
19
  // eslint-plugin-jsdoc warning
18
20
  "jsdoc/require-property": 0,
19
21
  // =airbnb, >eslint:
package/lib/api/main.js CHANGED
@@ -14,7 +14,7 @@ const { toSqlDdl } = require('../render/toSql');
14
14
  const { compareModels } = require('../modelCompare/compare');
15
15
  const sortViews = require('../model/sortViews');
16
16
  const { getResultingName } = require('../model/csnUtils');
17
- const timetrace = require('../utils/timetrace');
17
+ const { timetrace } = require('../utils/timetrace');
18
18
  const { transformForHanaWithCsn } = require('../transform/forHanaNew');
19
19
 
20
20
  /**
@@ -135,7 +135,7 @@ function odataInternal(csn, internalOptions) {
135
135
  * Return a odata-transformed CSN
136
136
  *
137
137
  * @param {CSN.Model} csn Clean input CSN
138
- * @param {oDataOptions} [options={}] Options
138
+ * @param {ODataOptions} [options={}] Options
139
139
  * @returns {oDataCSN} Return an oData-pre-processed CSN
140
140
  */
141
141
  function odata(csn, options = {}) {
@@ -159,12 +159,13 @@ function cdl(csn, externalOptions = {}) {
159
159
  * Transform a CSN like to.sql
160
160
  *
161
161
  * @param {CSN.Model} csn Plain input CSN
162
- * @param {sqlOptions} [options={}] Options
162
+ * @param {SqlOptions} [options={}] Options
163
163
  * @returns {CSN.Model} CSN transformed like to.sql
164
164
  * @private
165
165
  */
166
166
  function forSql(csn, options = {}) {
167
167
  const internalOptions = prepareOptions.to.sql(options);
168
+ internalOptions.transformation = 'sql';
168
169
  internalOptions.toSql.csn = true;
169
170
  return backends.toSqlWithCsn(csn, internalOptions).csn;
170
171
  }
@@ -202,11 +203,12 @@ function forHdbcds(csn, options = {}) {
202
203
  * Process the given CSN into SQL.
203
204
  *
204
205
  * @param {CSN.Model} csn A clean input CSN
205
- * @param {sqlOptions} [options={}] Options
206
+ * @param {SqlOptions} [options={}] Options
206
207
  * @returns {SQL[]} Array of SQL statements, tables first, views second
207
208
  */
208
209
  function sql(csn, options = {}) {
209
210
  const internalOptions = prepareOptions.to.sql(options);
211
+ internalOptions.transformation = 'sql';
210
212
 
211
213
  // we need the CSN for view sorting
212
214
  internalOptions.toSql.csn = true;
@@ -454,7 +456,7 @@ function hdbcds(csn, options = {}) {
454
456
  * Generate a edm document for the given service
455
457
  *
456
458
  * @param {CSN|oDataCSN} csn Clean input CSN or a pre-transformed CSN
457
- * @param {oDataOptions} [options={}] Options
459
+ * @param {ODataOptions} [options={}] Options
458
460
  * @returns {edm} The JSON representation of the service
459
461
  */
460
462
  function edm(csn, options = {}) {
@@ -484,7 +486,7 @@ edm.all = edmall;
484
486
  * Generate edm documents for all services
485
487
  *
486
488
  * @param {CSN|oDataCSN} csn Clean input CSN or a pre-transformed CSN
487
- * @param {oDataOptions} [options={}] Options
489
+ * @param {ODataOptions} [options={}] Options
488
490
  * @returns {edms} { <service>:<JSON representation>, ...}
489
491
  */
490
492
  function edmall(csn, options = {}) {
@@ -516,7 +518,7 @@ function edmall(csn, options = {}) {
516
518
  * Generate a edmx document for the given service
517
519
  *
518
520
  * @param {CSN|oDataCSN} csn Clean input CSN or a pre-transformed CSN
519
- * @param {oDataOptions} [options={}] Options
521
+ * @param {ODataOptions} [options={}] Options
520
522
  * @returns {edmx} The XML representation of the service
521
523
  */
522
524
  function edmx(csn, options = {}) {
@@ -547,7 +549,7 @@ edmx.all = edmxall;
547
549
  * Generate edmx documents for all services
548
550
  *
549
551
  * @param {CSN|oDataCSN} csn Clean input CSN or a pre-transformed CSN
550
- * @param {oDataOptions} [options={}] Options
552
+ * @param {ODataOptions} [options={}] Options
551
553
  * @returns {edmxs} { <service>:<XML representation>, ...}
552
554
  */
553
555
  function edmxall(csn, options = {}) {
@@ -709,20 +711,6 @@ function publishCsnProcessor( processor, _name ) {
709
711
  * @property {Array} [messages] Allows collecting all messages in the options instead of printing them to stderr.
710
712
  */
711
713
 
712
- /**
713
- * Options available for all oData-based functions
714
- *
715
- * @typedef {object} oDataOptions
716
- * @property {object} [beta] Enable experimental features - not for productive use!
717
- * @property {boolean} [longAutoexposed=false] Deprecated: Produce long names (with underscores) for autoexposed entities
718
- * @property {Map<string, number>} [severities={}] Map of message-id and severity that allows setting the severity for the given message
719
- * @property {Array} [messages] Allows collecting all messages in the options instead of printing them to stderr.
720
- * @property {oDataVersion} [odataVersion='v4'] Odata version to use
721
- * @property {oDataFormat} [odataFormat='flat'] Wether to generate oData as flat or as structured. Structured only with v4.
722
- * @property {NamingMode} [sqlMapping='plain'] Naming mode to use
723
- * @property {string} [service] If a single service is to be rendered
724
- */
725
-
726
714
  /**
727
715
  * Options available for to.hdi
728
716
  *
@@ -747,20 +735,6 @@ function publishCsnProcessor( processor, _name ) {
747
735
  * @property {Array} [messages] Allows collecting all messages in the options instead of printing them to stderr.
748
736
  */
749
737
 
750
- /**
751
- * Options available for to.sql
752
- *
753
- * @typedef {object} sqlOptions
754
- * @property {NamingMode} [sqlMapping='plain'] Naming mode to use
755
- * @property {SQLDialect} [sqlDialect='sqlite'] SQL dialect to use
756
- * @property {object} [magicVars] Object containing values for magic variables like "$user"
757
- * @property {string} [magicVars.locale] Value for the "$user.locale" in "sqlite" dialect
758
- * @property {string} [magicVars.user] Value for the "$user" variable in "sqlite" dialect
759
- * @property {object} [beta] Enable experimental features - not for productive use!
760
- * @property {boolean} [longAutoexposed=false] Deprecated: Produce long names (with underscores) for autoexposed entities
761
- * @property {Map<string, number>} [severities={}] Map of message-id and severity that allows setting the severity for the given message
762
- * @property {Array} [messages] Allows collecting all messages in the options instead of printing them to stderr.
763
- */
764
738
 
765
739
  /**
766
740
  * A fresh (just compiled, not transformed) CSN