@sap/cds-compiler 5.8.0 → 5.9.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 (89) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/bin/cds_remove_invalid_whitespace.js +5 -3
  3. package/bin/cds_update_identifiers.js +9 -6
  4. package/bin/cdsc.js +79 -59
  5. package/bin/cdsse.js +14 -10
  6. package/bin/cdsv2m.js +3 -1
  7. package/lib/api/options.js +28 -6
  8. package/lib/base/message-registry.js +15 -4
  9. package/lib/checks/validator.js +3 -0
  10. package/lib/compiler/base.js +1 -1
  11. package/lib/compiler/checks.js +70 -50
  12. package/lib/compiler/extend.js +1 -1
  13. package/lib/compiler/generate.js +8 -2
  14. package/lib/compiler/index.js +1 -1
  15. package/lib/compiler/lsp-api.js +1 -1
  16. package/lib/compiler/propagator.js +2 -2
  17. package/lib/compiler/resolve.js +78 -31
  18. package/lib/compiler/shared.js +3 -3
  19. package/lib/compiler/tweak-assocs.js +1 -1
  20. package/lib/compiler/utils.js +10 -0
  21. package/lib/compiler/xpr-rewrite.js +1 -1
  22. package/lib/edm/annotations/edmJson.js +42 -39
  23. package/lib/edm/annotations/genericTranslation.js +55 -55
  24. package/lib/edm/annotations/preprocessAnnotations.js +5 -5
  25. package/lib/edm/csn2edm.js +21 -16
  26. package/lib/edm/edm.js +62 -62
  27. package/lib/edm/edmAnnoPreprocessor.js +2 -2
  28. package/lib/edm/edmInboundChecks.js +1 -1
  29. package/lib/edm/edmPreprocessor.js +32 -32
  30. package/lib/edm/edmUtils.js +8 -8
  31. package/lib/gen/CdlGrammar.checksum +1 -1
  32. package/lib/gen/CdlParser.js +77 -81
  33. package/lib/gen/Dictionary.json +3062 -3072
  34. package/lib/gen/language.checksum +1 -1
  35. package/lib/gen/language.interp +1 -1
  36. package/lib/gen/languageParser.js +1238 -1236
  37. package/lib/json/from-csn.js +1 -1
  38. package/lib/json/to-csn.js +30 -3
  39. package/lib/language/genericAntlrParser.js +16 -0
  40. package/lib/main.d.ts +79 -1
  41. package/lib/model/csnRefs.js +12 -5
  42. package/lib/model/xprAsTree.js +71 -0
  43. package/lib/modelCompare/utils/filter.js +1 -1
  44. package/lib/optionProcessor.js +46 -32
  45. package/lib/parsers/CdlGrammar.g4 +33 -28
  46. package/lib/parsers/Lexer.js +1 -1
  47. package/lib/parsers/XprTree.js +25 -16
  48. package/lib/render/toCdl.js +902 -414
  49. package/lib/render/toHdbcds.js +1 -1
  50. package/lib/render/toSql.js +8 -0
  51. package/lib/render/utils/common.js +2 -2
  52. package/lib/render/utils/operators.js +160 -0
  53. package/lib/render/utils/pretty.js +337 -0
  54. package/lib/sql-identifier.js +7 -9
  55. package/lib/transform/addTenantFields.js +39 -41
  56. package/lib/transform/db/applyTransformations.js +4 -4
  57. package/lib/transform/db/assertUnique.js +6 -5
  58. package/lib/transform/db/associations.js +3 -3
  59. package/lib/transform/db/assocsToQueries/transformExists.js +13 -13
  60. package/lib/transform/db/assocsToQueries/utils.js +8 -0
  61. package/lib/transform/db/backlinks.js +19 -14
  62. package/lib/transform/db/constraints.js +6 -6
  63. package/lib/transform/db/expansion.js +1 -1
  64. package/lib/transform/db/flattening.js +2 -2
  65. package/lib/transform/db/groupByOrderBy.js +1 -1
  66. package/lib/transform/db/processSqlServices.js +3 -3
  67. package/lib/transform/db/rewriteCalculatedElements.js +2 -2
  68. package/lib/transform/db/temporal.js +7 -9
  69. package/lib/transform/db/views.js +6 -6
  70. package/lib/transform/draft/odata.js +2 -0
  71. package/lib/transform/effective/annotations.js +1 -1
  72. package/lib/transform/effective/associations.js +1 -1
  73. package/lib/transform/effective/main.js +1 -0
  74. package/lib/transform/effective/service.js +2 -2
  75. package/lib/transform/forRelationalDB.js +11 -5
  76. package/lib/transform/localized.js +2 -0
  77. package/lib/transform/odata/adaptAnnotationRefs.js +10 -9
  78. package/lib/transform/odata/createForeignKeys.js +1 -1
  79. package/lib/transform/odata/flattening.js +2 -1
  80. package/lib/transform/parseExpr.js +2 -2
  81. package/lib/transform/transformUtils.js +9 -7
  82. package/lib/transform/translateAssocsToJoins.js +0 -2
  83. package/lib/transform/universalCsn/coreComputed.js +2 -2
  84. package/lib/utils/moduleResolve.js +7 -5
  85. package/package.json +1 -1
  86. package/share/messages/def-upcoming-virtual-change.md +55 -0
  87. package/share/messages/file-unexpected-case-mismatch.md +61 -0
  88. package/share/messages/message-explanations.json +2 -0
  89. package/lib/transform/braceExpression.js +0 -77
package/CHANGELOG.md CHANGED
@@ -7,6 +7,43 @@
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 5.9.0 - 2025-03-28
11
+
12
+ ### Added
13
+
14
+ - compiler:
15
+ + Generated entities for compositions of named aspects now have an `include` on the named aspect,
16
+ inheriting actions from the aspect. This can be disabled via option `compositionIncludes: false`.
17
+ + A warning is emitted for selected elements that are explicitly `virtual`, whose
18
+ behavior will change in cds-compiler v6.
19
+ + New warning for structures having a scalar default value.
20
+ + New warning for localized structures, as they are not fully supported by the compiler.
21
+ + The new parser (`newParser: true`) now supports operator `==`.
22
+ - to.cdl:
23
+ + Definitions can now be rendered nested in services. A common namespace can be extracted, too.
24
+ To use it, enabled options `renderCdlDefinitionNesting` and `renderCdlCommonNamespace`.
25
+ + Annotation array values are pretty-printed to reduce whitespace.
26
+ - for.effective: Property `namespace` is no longer part of effective CSN.
27
+ - for.sql/hdi:
28
+ - The new operator `==` is rendered as `IS NOT DISTINCT FROM` or an equivalent expression.
29
+ - Using option `booleanEquality`, operator `!=` is rendered as `IS DISTINCT FROM` or an equivalent expression.
30
+
31
+ ### Changed
32
+
33
+ - Update OData vocabularies: 'Common', 'Hierarchy'
34
+
35
+ ### Fixed
36
+
37
+ - to.odata: Annotation expressions using `LabeledElement` were not correctly rendered into EDMX.
38
+
39
+
40
+ ## Version 5.8.2 - 2025-03-07
41
+
42
+ ### Fixed
43
+
44
+ - for.odata: Generate foreign key elements for events again.
45
+
46
+
10
47
  ## Version 5.8.0 - 2025-02-27
11
48
 
12
49
  ### Added
@@ -21,6 +21,8 @@
21
21
  // Note that you need to update the path to this script in the commands above.
22
22
  //
23
23
 
24
+ /* eslint no-process-exit: 0, no-console: 0 */
25
+
24
26
  'use strict';
25
27
 
26
28
  const parsers = require('../lib/parsers');
@@ -36,7 +38,7 @@ if (filepath === '--help' || filepath === '-h')
36
38
  exitError();
37
39
 
38
40
  if (cliArgs.length !== 1)
39
- exitError(`Expected exactly one argument, ${cliArgs.length} given`);
41
+ exitError(`Expected exactly one argument, ${ cliArgs.length } given`);
40
42
 
41
43
  if (!filepath)
42
44
  exitError('Expected non-empty filepath as argument!');
@@ -70,7 +72,7 @@ function modernizeWhitespace( source, filename ) {
70
72
  errors.forEach((msg) => {
71
73
  console.error(msg.toString());
72
74
  });
73
- console.error(`Found ${errors.length} errors! \n`);
75
+ console.error(`Found ${ errors.length } errors! \n`);
74
76
  exitError('The CDS parser emitted errors. Fix them first and try again.');
75
77
  }
76
78
 
@@ -132,5 +134,5 @@ function exitError( msg ) {
132
134
 
133
135
  function usage() {
134
136
  console.error('');
135
- console.error(`usage: ${path.basename(process.argv[1])} <filename>`);
137
+ console.error(`usage: ${ path.basename(process.argv[1]) } <filename>`);
136
138
  }
@@ -20,6 +20,8 @@
20
20
  // Note that you need to update the path to this script in the commands above.
21
21
  //
22
22
 
23
+ /* eslint no-process-exit: 0, no-console: 0 */
24
+
23
25
  'use strict';
24
26
 
25
27
  const parsers = require('../lib/parsers');
@@ -35,7 +37,7 @@ if (filepath === '--help' || filepath === '-h')
35
37
  exitError();
36
38
 
37
39
  if (cliArgs.length !== 1)
38
- exitError(`Expected exactly one argument, ${cliArgs.length} given`);
40
+ exitError(`Expected exactly one argument, ${ cliArgs.length } given`);
39
41
 
40
42
  if (!filepath)
41
43
  exitError('Expected non-empty filepath as argument!');
@@ -68,7 +70,7 @@ function modernizeIdentifierStyle( source, filename ) {
68
70
  errors.forEach((msg) => {
69
71
  console.error(msg.toString());
70
72
  });
71
- console.error(`Found ${errors.length} errors! \n`);
73
+ console.error(`Found ${ errors.length } errors! \n`);
72
74
  exitError('The CDS parser emitted errors. Fix them first and try again.');
73
75
  }
74
76
 
@@ -88,10 +90,11 @@ function modernizeIdentifierStyle( source, filename ) {
88
90
  const newIdentText = toNewIdentStyle(identToken.text);
89
91
 
90
92
  if (!identToken.stop)
91
- throw new Error(`INTERNAL ERROR: Identifier at ${identToken.start} has no end!`);
93
+ throw new Error(`INTERNAL ERROR: Identifier at ${ identToken.start } has no end!`);
92
94
 
93
95
  const start = identToken.start + currentOffset;
94
- const end = identToken.stop + currentOffset + 1; // end points at the position *before* the character
96
+ // 'end' points at the position *before* the character
97
+ const end = identToken.stop + currentOffset + 1;
95
98
 
96
99
  source = replaceSliceInSource(source, start, end, newIdentText);
97
100
 
@@ -105,7 +108,7 @@ function modernizeIdentifierStyle( source, filename ) {
105
108
  ident = ident.replace(/""/g, '"');
106
109
  ident = ident.replace(/]/g, ']]');
107
110
 
108
- return `![${ident}]`;
111
+ return `![${ ident }]`;
109
112
  }
110
113
  }
111
114
 
@@ -136,5 +139,5 @@ function exitError( msg ) {
136
139
 
137
140
  function usage() {
138
141
  console.error('');
139
- console.error(`usage: ${path.basename(process.argv[1])} <filename>`);
142
+ console.error(`usage: ${ path.basename(process.argv[1]) } <filename>`);
140
143
  }
package/bin/cdsc.js CHANGED
@@ -17,7 +17,7 @@
17
17
 
18
18
  const compiler = require('../lib/compiler');
19
19
  const main = require('../lib/main');
20
- const { for_sql, for_hdi, for_hdbcds } = require('../lib/api/main');
20
+ const { for_sql: forSql, for_hdi: forHdi, for_hdbcds: forHdbcds } = require('../lib/api/main');
21
21
  const { compactModel } = require('../lib/json/to-csn');
22
22
  const { toRename: _toRename } = require('../lib/render/toRename');
23
23
  const util = require('util');
@@ -48,7 +48,7 @@ class ProcessExitError extends Error {
48
48
  }
49
49
 
50
50
  try {
51
- cdsc_main();
51
+ cdscMain();
52
52
  }
53
53
  catch (err) {
54
54
  // This whole try/catch is only here because process.exit does not work in combination with
@@ -85,7 +85,7 @@ function remapCmdOptions( options, command ) {
85
85
  delete options[command];
86
86
  }
87
87
 
88
- function cdsc_main() {
88
+ function cdscMain() {
89
89
  if (process.argv.some(arg => arg === '-i' || arg === '--stdin'))
90
90
  optionProcessor.makePositionalArgumentsOptional();
91
91
 
@@ -94,13 +94,13 @@ function cdsc_main() {
94
94
 
95
95
  // Deal with '--version' explicitly
96
96
  if (cmdLine.options.version) {
97
- process.stdout.write(`${main.version()}\n`);
97
+ process.stdout.write(`${ main.version() }\n`);
98
98
  throw new ProcessExitError(0);
99
99
  }
100
100
  // Deal with '--help' explicitly
101
101
  if (cmdLine.command) {
102
102
  // Command specific help
103
- if (cmdLine.options.help || cmdLine.options[cmdLine.command] && cmdLine.options[cmdLine.command].help)
103
+ if (cmdLine.options.help || cmdLine.options[cmdLine.command]?.help)
104
104
  displayUsage(null, optionProcessor.commands[cmdLine.command].helpText, 0);
105
105
  }
106
106
  else if (cmdLine.options.help) {
@@ -111,7 +111,7 @@ function cdsc_main() {
111
111
  if (cmdLine.unknownOptions.length > 0) {
112
112
  // Print an INFO message about unknown options but
113
113
  // continue with defaults and do not abort execution.
114
- cmdLine.unknownOptions.forEach(msg => process.stderr.write(`cdsc: INFO: ${msg}\n`));
114
+ cmdLine.unknownOptions.forEach(msg => process.stderr.write(`cdsc: INFO: ${ msg }\n`));
115
115
  }
116
116
 
117
117
  // Report complaints if any
@@ -175,18 +175,19 @@ function cdsc_main() {
175
175
 
176
176
  const to = cmdLine.options.toSql ? 'toSql' : 'toHana';
177
177
  if (cmdLine.options[to]) {
178
+ const opt = cmdLine.options[to];
178
179
  // remap string values in options to boolean
179
- if (cmdLine.options[to].assertIntegrity &&
180
- (cmdLine.options[to].assertIntegrity === 'true' ||
181
- cmdLine.options[to].assertIntegrity === 'false')
180
+ if (opt.assertIntegrity &&
181
+ (opt.assertIntegrity === 'true' ||
182
+ opt.assertIntegrity === 'false')
182
183
  )
183
- cmdLine.options[to].assertIntegrity = cmdLine.options[to].assertIntegrity === 'true';
184
+ opt.assertIntegrity = opt.assertIntegrity === 'true';
184
185
 
185
- if (cmdLine.options[to].withHanaAssociations)
186
- cmdLine.options[to].withHanaAssociations = cmdLine.options[to].withHanaAssociations !== 'false';
186
+ if (opt.withHanaAssociations)
187
+ opt.withHanaAssociations = opt.withHanaAssociations !== 'false';
187
188
 
188
- if (cmdLine.options[to].betterSqliteSessionVariables)
189
- cmdLine.options[to].betterSqliteSessionVariables = cmdLine.options[to].betterSqliteSessionVariables === 'true';
189
+ if (opt.betterSqliteSessionVariables)
190
+ opt.betterSqliteSessionVariables = opt.betterSqliteSessionVariables === 'true';
190
191
  }
191
192
 
192
193
  // Enable all beta-flags if betaMode is set to true
@@ -199,7 +200,7 @@ function cdsc_main() {
199
200
  cmdLine.options.testMode = (num > 0)
200
201
  ? num
201
202
  : Math.floor( Math.random() * 4294967296 ) + 1;
202
- console.error( `Running ‘${cmdLine.command}’ with test-mode shuffle ${cmdLine.options.testMode} …` );
203
+ console.error( `Running ‘${ cmdLine.command }’ with test-mode shuffle ${ cmdLine.options.testMode } …` );
203
204
  }
204
205
 
205
206
  // If set through CLI (and not options file), `deprecated` and `moduleLookupDirectories`
@@ -218,10 +219,16 @@ function cdsc_main() {
218
219
  cmdLine.options.fallbackParser ??= 'auto!';
219
220
 
220
221
  if (cmdLine.options[cmdLine.command]?.transitiveLocalizedViews) {
221
- cmdLine.options.fewerLocalizedViews = !cmdLine.options[cmdLine.command].transitiveLocalizedViews
222
+ cmdLine.options.fewerLocalizedViews
223
+ = !cmdLine.options[cmdLine.command].transitiveLocalizedViews;
222
224
  delete cmdLine.options[cmdLine.command].transitiveLocalizedViews;
223
225
  }
224
226
 
227
+ if (cmdLine.options.noCompositionIncludes) {
228
+ cmdLine.options.compositionIncludes = false;
229
+ delete cmdLine.options.noCompositionIncludes;
230
+ }
231
+
225
232
  parseSeverityOptions(cmdLine);
226
233
 
227
234
  // Do the work for the selected command
@@ -239,11 +246,11 @@ function cdsc_main() {
239
246
  */
240
247
  function validateDirectBackendOption( command, options, args ) {
241
248
  if (![ 'toCdl', 'toOdata', 'toHana', 'toCsn', 'toSql', 'forJava' ].includes(command)) {
242
- displayUsage(`Option '--direct-backend' can't be used with command '${command}'`,
249
+ displayUsage(`Option '--direct-backend' can't be used with command '${ command }'`,
243
250
  optionProcessor.helpText, 2);
244
251
  }
245
252
  if (!options.stdin && (!args.files || args.files.length !== 1)) {
246
- displayUsage(`Option '--direct-backend' expects exactly one JSON file, but ${args.files?.length || 'none'} given`,
253
+ displayUsage(`Option '--direct-backend' expects exactly one JSON file, but ${ args.files?.length || 'none' } given`,
247
254
  optionProcessor.helpText, 2);
248
255
  }
249
256
  const filename = args.files?.[0];
@@ -258,14 +265,14 @@ function displayUsage( error, helpText, code ) {
258
265
  // Display non-error output (like help) to stdout
259
266
  const out = (code === 0 && !error) ? process.stdout : process.stderr;
260
267
  // Display help text first, error at the end (more readable, no scrolling)
261
- out.write(`${helpText}\n`);
268
+ out.write(`${ helpText }\n`);
262
269
  if (error) {
263
270
  if (error instanceof Array) {
264
- const errors = error.map(err => `cdsc: ERROR: ${err}`).join('\n');
265
- out.write(`${errors}\n`);
271
+ const errors = error.map(err => `cdsc: ERROR: ${ err }`).join('\n');
272
+ out.write(`${ errors }\n`);
266
273
  }
267
274
  else {
268
- out.write(`cdsc: ERROR: ${error}\n`);
275
+ out.write(`cdsc: ERROR: ${ error }\n`);
269
276
  }
270
277
  }
271
278
  throw new ProcessExitError(code);
@@ -284,7 +291,8 @@ async function createTemporaryFileFromStdin() {
284
291
  return file;
285
292
  }
286
293
 
287
- // Executes a command line that has been translated to 'command' (what to do), 'options' (how) and 'args' (which files)
294
+ // Executes a command line that has been translated to 'command' (what to do),
295
+ // 'options' (how) and 'args' (which files)
288
296
  async function executeCommandLine( command, options, args ) {
289
297
  const normalizeFilename = options.testMode && process.platform === 'win32';
290
298
  const messageLevels = {
@@ -319,7 +327,7 @@ async function executeCommandLine( command, options, args ) {
319
327
  };
320
328
 
321
329
  if (!commands[command] && !commandsWithoutCompilation[command])
322
- throw new Error(`Missing implementation for command ${command}`);
330
+ throw new Error(`Missing implementation for command ${ command }`);
323
331
 
324
332
  remapCmdOptions( options, command );
325
333
 
@@ -352,13 +360,16 @@ async function executeCommandLine( command, options, args ) {
352
360
  const csn = options.directBackend ? model : compactModel(model, options);
353
361
  const cdlResult = main.to.cdl(csn, options);
354
362
  for (const name in cdlResult)
355
- writeToFileOrDisplay(options.out, `${name}.cds`, cdlResult[name]);
363
+ writeToFileOrDisplay(options.out, `${ name }.cds`, cdlResult[name]);
356
364
 
357
365
  return model;
358
366
  }
359
367
 
360
368
  function forEffective( model ) {
361
- const features = [ 'resolveSimpleTypes', 'resolveProjections', 'remapOdataAnnotations', 'keepLocalized' ];
369
+ const features = [
370
+ 'resolveSimpleTypes', 'resolveProjections',
371
+ 'remapOdataAnnotations', 'keepLocalized',
372
+ ];
362
373
  for (const feature of features) {
363
374
  if (options[feature]) // map to boolean equivalent
364
375
  options[feature] = options[feature] === 'true';
@@ -408,7 +419,7 @@ async function executeCommandLine( command, options, args ) {
408
419
  const csn = options.directBackend ? model : compactModel(model, options);
409
420
 
410
421
  if (options.csn) {
411
- displayNamedCsn(for_hdbcds(csn, options), 'hana_csn');
422
+ displayNamedCsn(forHdbcds(csn, options), 'hana_csn');
412
423
  }
413
424
  else {
414
425
  const hanaResult = main.to.hdbcds(csn, options);
@@ -438,12 +449,12 @@ async function executeCommandLine( command, options, args ) {
438
449
  else if (options.json) {
439
450
  const result = main.to.edm.all(csn, options);
440
451
  for (const serviceName in result)
441
- writeToFileOrDisplay(options.out, `${serviceName}.json`, result[serviceName]);
452
+ writeToFileOrDisplay(options.out, `${ serviceName }.json`, result[serviceName]);
442
453
  }
443
454
  else {
444
455
  const result = main.to.edmx.all(csn, options);
445
456
  for (const serviceName in result)
446
- writeToFileOrDisplay(options.out, `${serviceName}.xml`, result[serviceName]);
457
+ writeToFileOrDisplay(options.out, `${ serviceName }.xml`, result[serviceName]);
447
458
  }
448
459
  return model;
449
460
  }
@@ -457,13 +468,13 @@ async function executeCommandLine( command, options, args ) {
457
468
  const csn = options.directBackend ? model : compactModel(model, options);
458
469
  const messageFunctions = makeMessageFunction(csn, options, 'to.rename');
459
470
  const renameResult = _toRename(csn, options, messageFunctions);
460
- let storedProcedure = `PROCEDURE RENAME_${renameResult.options.sqlMapping.toUpperCase()}_TO_PLAIN LANGUAGE SQLSCRIPT AS BEGIN\n`;
471
+ let storedProcedure = `PROCEDURE RENAME_${ renameResult.options.sqlMapping.toUpperCase() }_TO_PLAIN LANGUAGE SQLSCRIPT AS BEGIN\n`;
461
472
  for (const name in renameResult.rename) {
462
- storedProcedure += ` --\n -- ${name}\n --\n`;
473
+ storedProcedure += ` --\n -- ${ name }\n --\n`;
463
474
  storedProcedure += renameResult.rename[name];
464
475
  }
465
476
  storedProcedure += 'END;\n';
466
- writeToFileOrDisplay(options.out, `storedProcedure_${renameResult.options.sqlMapping}_to_plain.sql`, storedProcedure, true);
477
+ writeToFileOrDisplay(options.out, `storedProcedure_${ renameResult.options.sqlMapping }_to_plain.sql`, storedProcedure, true);
467
478
  return model;
468
479
  }
469
480
 
@@ -476,9 +487,9 @@ async function executeCommandLine( command, options, args ) {
476
487
  Object.keys(alterConstraintsResult).forEach((id) => {
477
488
  const renderedConstraintStatement = alterConstraintsResult[id];
478
489
  if (src === 'hdi')
479
- writeToFileOrDisplay(options.out, `${id}.hdbconstraint`, renderedConstraintStatement);
490
+ writeToFileOrDisplay(options.out, `${ id }.hdbconstraint`, renderedConstraintStatement);
480
491
  else
481
- writeToFileOrDisplay(options.out, `${id}.sql`, renderedConstraintStatement);
492
+ writeToFileOrDisplay(options.out, `${ id }.sql`, renderedConstraintStatement);
482
493
  });
483
494
  }
484
495
 
@@ -488,7 +499,7 @@ async function executeCommandLine( command, options, args ) {
488
499
  const csn = options.directBackend ? model : compactModel(model, options);
489
500
  if (options.src === 'hdi') {
490
501
  if (options.csn) {
491
- displayNamedCsn(for_hdi(csn, options), 'hdi_csn');
502
+ displayNamedCsn(forHdi(csn, options), 'hdi_csn');
492
503
  }
493
504
  else {
494
505
  const hdiResult = main.to.hdi(csn, options);
@@ -497,7 +508,7 @@ async function executeCommandLine( command, options, args ) {
497
508
  }
498
509
  }
499
510
  else if (options.csn) {
500
- displayNamedCsn(for_sql(csn, options), 'sql_csn');
511
+ displayNamedCsn(forSql(csn, options), 'sql_csn');
501
512
  }
502
513
  else {
503
514
  const sqlResult = main.to.sql(csn, options);
@@ -513,7 +524,7 @@ async function executeCommandLine( command, options, args ) {
513
524
  }
514
525
 
515
526
  if (!hasMessageExplanation(args.messageId))
516
- console.error(`Message '${args.messageId}' does not have an explanation!`);
527
+ console.error(`Message '${ args.messageId }' does not have an explanation!`);
517
528
  else
518
529
  console.log(explainMessage(args.messageId));
519
530
  }
@@ -597,12 +608,13 @@ async function executeCommandLine( command, options, args ) {
597
608
  else {
598
609
  let hasAtLeastOneExplanation = false;
599
610
  messages.filter(msg => messageLevels[msg.severity] <= options.warning).forEach((msg) => {
600
- hasAtLeastOneExplanation = hasAtLeastOneExplanation || main.hasMessageExplanation(msg.messageId);
611
+ hasAtLeastOneExplanation = hasAtLeastOneExplanation ||
612
+ main.hasMessageExplanation(msg.messageId);
601
613
  log(main.messageStringMultiline(msg, msgConfig));
602
614
  log(); // newline
603
615
  });
604
616
  if (!options.noMessageId && hasAtLeastOneExplanation)
605
- log(`${colorTerm.asHelp('help')}: Messages marked with '…' have an explanation text. Use \`cdsc explain <message-id>\` for a more detailed error description.`);
617
+ log(`${ colorTerm.asHelp('help') }: Messages marked with '…' have an explanation text. Use \`cdsc explain <message-id>\` for a more detailed error description.`);
606
618
  }
607
619
  return model;
608
620
  }
@@ -613,9 +625,9 @@ async function executeCommandLine( command, options, args ) {
613
625
  // written in raw form to '<name>_raw.txt'.
614
626
  function displayNamedXsn( xsn, name ) {
615
627
  if (options.rawOutput)
616
- writeToFileOrDisplay(options.out, `${name}_raw.txt`, util.inspect(reveal(xsn, options.rawOutput), false, null), true);
628
+ writeToFileOrDisplay(options.out, `${ name }_raw.txt`, util.inspect(reveal(xsn, options.rawOutput), false, null), true);
617
629
  else if (options.internalMsg)
618
- writeToFileOrDisplay(options.out, `${name}_raw.txt`, util.inspect(reveal(xsn).messages, { depth: null, maxArrayLength: null }), true);
630
+ writeToFileOrDisplay(options.out, `${ name }_raw.txt`, util.inspect(reveal(xsn).messages, { depth: null, maxArrayLength: null }), true);
619
631
  else if (!options.parseOnly) // no output if parseOnly but not rawOutput
620
632
  displayNamedCsn(compactModel(xsn, options), name);
621
633
  }
@@ -639,29 +651,37 @@ async function executeCommandLine( command, options, args ) {
639
651
  if (options.enrichCsn)
640
652
  enrichCsn( csn, options );
641
653
 
642
- if (options.internalMsg) {
643
- writeToFileOrDisplay(options.out, `${name}_raw.txt`, options.messages, true);
644
- }
645
- else if (!options.internalMsg) {
646
- writeToFileOrDisplay(options.out, `${name}.json`, csn, true);
647
- }
654
+ if (options.internalMsg)
655
+ writeToFileOrDisplay(options.out, `${ name }_raw.txt`, options.messages, true);
656
+
657
+ else if (!options.internalMsg)
658
+ writeToFileOrDisplay(options.out, `${ name }.json`, csn, true);
648
659
  }
649
660
 
650
- // Write the result 'content' to a file 'filename' in directory 'dir', except if 'dir' is '-'.
651
- // In that case, display 'content' to stdout.
652
- // If 'content' is not a string, JSON-stringify it
653
- // If displaying to stdout, prepend a headline containing 'filename', unless 'omitHeadline' is set.
654
- // For filenames, illegal characters (slash, backslash, colon) are replaced by '_'.
661
+ /**
662
+ * Write the result 'content' to a file 'filename' in directory 'dir', except if 'dir' is '-'.
663
+ * In that case, display 'content' to stdout.
664
+ * If 'content' is not a string, JSON-stringify it
665
+ * If displaying to stdout, prepend a headline containing 'filename',
666
+ * unless 'omitHeadline' is set.
667
+ * For filenames, illegal characters (slash, backslash, colon) are replaced by '_'.
668
+ *
669
+ * @param {string} dir
670
+ * @param {string} fileName
671
+ * @param {string} content
672
+ * @param {boolean} [omitHeadline]
673
+ */
655
674
  function writeToFileOrDisplay( dir, fileName, content, omitHeadline = false ) {
656
675
  if (options.internalMsg)
657
676
  return;
658
677
  fileName = fileName.replace(/[:/\\]/g, '_');
659
678
 
660
- // replace all dots with underscore to get deployable .hdbcds sources (except the one before the file extension)
679
+ // replace all dots with underscore to get deployable .hdbcds sources
680
+ // (except the one before the file extension)
661
681
  if (options.transformation === 'hdbcds')
662
682
  fileName = fileName.replace(/\.(?=.*?\.)/g, '_');
663
683
 
664
- if (!(content instanceof String || typeof content === 'string'))
684
+ if (typeof content !== 'string')
665
685
  content = JSON.stringify(content, null, 2);
666
686
 
667
687
  if (dir === '-') {
@@ -672,10 +692,10 @@ async function executeCommandLine( command, options, args ) {
672
692
  sql: true, hdbconstraint: true, hdbtable: true, hdbview: true,
673
693
  };
674
694
  const commentStarter = fileName.split('.').pop() in sqlTypes ? '--$' : '//';
675
- process.stdout.write(`${commentStarter} ------------------- ${fileName} -------------------\n`);
695
+ process.stdout.write(`${ commentStarter } ------------------- ${ fileName } -------------------\n`);
676
696
  }
677
697
 
678
- process.stdout.write(`${content}\n`);
698
+ process.stdout.write(`${ content }\n`);
679
699
  if (!omitHeadline)
680
700
  process.stdout.write('\n');
681
701
  }
@@ -730,8 +750,9 @@ function parseSeverityOptions({ options }) {
730
750
  debug: 'Debug',
731
751
  };
732
752
 
733
- // Note: We use a for loop to ensure that the order of the options on the command line is respected, i.e.
734
- // `--warn id --error id` would lead to `id` being reclassified as an error and not a warning.
753
+ // Note: We use a for loop to ensure that the order of the options on
754
+ // the command line is respected, i.e. `--warn id --error id` would
755
+ // lead to `id` being reclassified as an error and not a warning.
735
756
  for (const key in options) {
736
757
  switch (key) {
737
758
  case 'error':
@@ -754,4 +775,3 @@ function parseSeverityOptions({ options }) {
754
775
  }
755
776
  }
756
777
  }
757
-
package/bin/cdsse.js CHANGED
@@ -10,7 +10,8 @@
10
10
  // capabilities supported at the moments is: complete, find, lint.
11
11
  // Syntax highlighting is supported by ./cdshi.js.
12
12
 
13
- /* eslint no-console:off */
13
+ /* eslint @stylistic/js/max-len: 0, no-console: 0 */
14
+
14
15
  // @ts-nocheck
15
16
 
16
17
  'use strict';
@@ -28,8 +29,8 @@ const { availableBetaFlags: beta } = require('../lib/base/model');
28
29
 
29
30
  const { argv } = process;
30
31
  const cmd = commands[argv[2]];
31
- const line = Number.parseInt( argv[3] );
32
- const column = Number.parseInt( argv[4] );
32
+ const line = Number.parseInt( argv[3], 10 );
33
+ const column = Number.parseInt( argv[4], 10 );
33
34
  const file = argv[5];
34
35
  const frel = path.relative( '', file || '' );
35
36
  // TODO: proper realname
@@ -72,10 +73,11 @@ function complete( err, buf ) {
72
73
  hasId = tokensAt( buf, off.prefix, off.col, true );
73
74
  }
74
75
  if (hasId) {
75
- const src = `${buf.substring( 0, off.prefix )}__NO_SUCH_ID__${buf.substring( off.cursor )}`;
76
+ const src = `${ buf.substring( 0, off.prefix ) }__NO_SUCH_ID__${ buf.substring( off.cursor ) }`;
76
77
  const fname = path.resolve( '', file );
77
78
  compiler.compileX( [ file ], '', {
78
- newParser: true, attachValidNames: true, lintMode: true, beta, messages }, { [fname]: src } )
79
+ newParser: true, attachValidNames: true, lintMode: true, beta, messages,
80
+ }, { [fname]: src } )
79
81
  .then( ident, ident );
80
82
  }
81
83
  return true;
@@ -97,7 +99,7 @@ const autoNavigateKinds = {
97
99
  $navElement: art => art._origin,
98
100
  $tableAlias: art => art._origin,
99
101
  using: () => true,
100
- }
102
+ };
101
103
 
102
104
  // For finding the definition for reference under cursor, do the following
103
105
  // * replace identifier under cursor by an undefined name
@@ -112,7 +114,7 @@ function find( err, buf ) {
112
114
  if (off.prefix === off.cursor) // not at name
113
115
  return true;
114
116
  const messages = [];
115
- const src = `${buf.substring( 0, off.prefix )}__NO_SUCH_ID__${buf.substring( off.cursor )}`;
117
+ const src = `${ buf.substring( 0, off.prefix ) }__NO_SUCH_ID__${ buf.substring( off.cursor ) }`;
116
118
  const fname = path.resolve( '', file );
117
119
  compiler.compileX( [ file ], '', {
118
120
  newParser: true, attachValidNames: true, lintMode: true, beta, messages,
@@ -130,7 +132,7 @@ function find( err, buf ) {
130
132
  // TODO: why no _effectiveType for $navElement ?
131
133
  // TODO: display both the (first) inferred _and_ the "final" one
132
134
  if (art)
133
- console.log( `${locationString( art.name.location || art.location )}: Definition` );
135
+ console.log( `${ locationString( art.name.location || art.location ) }: Definition` );
134
136
  return true;
135
137
  }
136
138
  }
@@ -140,7 +142,9 @@ function lint( err, buf ) {
140
142
  return usage( err );
141
143
  const messages = [];
142
144
  const fname = path.resolve( '', file );
143
- compiler.compileX( [ file ], '', { newParser: true, lintMode: true, beta, messages }, { [fname]: buf } )
145
+ compiler.compileX( [ file ], '', {
146
+ newParser: true, lintMode: true, beta, messages,
147
+ }, { [fname]: buf } )
144
148
  .then( display, display );
145
149
  return true;
146
150
 
@@ -155,7 +159,7 @@ function lint( err, buf ) {
155
159
 
156
160
  function tokensAt( buf, _offset, col, symbol ) {
157
161
  const messages = [];
158
- const src = `${buf.substring( 0, _offset )}≠${buf.substring( _offset )}`;
162
+ const src = `${ buf.substring( 0, _offset ) }≠${ buf.substring( _offset ) }`;
159
163
  compiler.parseX( src, frel, { newParser: true, messages } );
160
164
  const et = messageAt( messages, 'expectedTokens', col ) || [];
161
165
  for (const n of et) {
package/bin/cdsv2m.js CHANGED
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ /* eslint @stylistic/js/max-len: 0, no-console: 0 */
4
+
3
5
  'use strict';
4
6
 
5
7
  // Very simple command-line interface to support model migration
@@ -45,6 +47,6 @@ function ria() {
45
47
  }
46
48
  for (const name in annotates) {
47
49
  const escaped = name.split('.').map(part => smartId(part)).join('.');
48
- console.log(`annotate ${escaped} with @cds.redirection.target: false;`);
50
+ console.log(`annotate ${ escaped } with @cds.redirection.target: false;`);
49
51
  }
50
52
  }