@sap/cds-compiler 3.4.4 → 3.5.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 (129) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/README.md +1 -0
  3. package/bin/cds_update_identifiers.js +5 -5
  4. package/bin/cdsc.js +12 -12
  5. package/doc/CHANGELOG_ARCHIVE.md +1 -1
  6. package/doc/CHANGELOG_BETA.md +9 -1
  7. package/doc/CHANGELOG_DEPRECATED.md +2 -0
  8. package/lib/api/main.js +58 -59
  9. package/lib/api/options.js +4 -2
  10. package/lib/api/validate.js +2 -2
  11. package/lib/base/cleanSymbols.js +2 -3
  12. package/lib/base/dictionaries.js +6 -6
  13. package/lib/base/error.js +2 -2
  14. package/lib/base/keywords.js +6 -6
  15. package/lib/base/location.js +11 -12
  16. package/lib/base/message-registry.js +124 -28
  17. package/lib/base/messages.js +247 -179
  18. package/lib/base/model.js +14 -11
  19. package/lib/base/node-helpers.js +9 -10
  20. package/lib/base/optionProcessorHelper.js +138 -129
  21. package/lib/checks/actionsFunctions.js +5 -5
  22. package/lib/checks/annotationsOData.js +4 -4
  23. package/lib/checks/arrayOfs.js +1 -1
  24. package/lib/checks/cdsPersistence.js +1 -1
  25. package/lib/checks/checkForTypes.js +3 -3
  26. package/lib/checks/defaultValues.js +3 -3
  27. package/lib/checks/elements.js +7 -7
  28. package/lib/checks/emptyOrOnlyVirtual.js +2 -2
  29. package/lib/checks/foreignKeys.js +1 -1
  30. package/lib/checks/invalidTarget.js +4 -4
  31. package/lib/checks/managedInType.js +1 -1
  32. package/lib/checks/managedWithoutKeys.js +1 -1
  33. package/lib/checks/nonexpandableStructured.js +5 -3
  34. package/lib/checks/nullableKeys.js +1 -1
  35. package/lib/checks/onConditions.js +5 -6
  36. package/lib/checks/parameters.js +1 -1
  37. package/lib/checks/queryNoDbArtifacts.js +2 -2
  38. package/lib/checks/selectItems.js +4 -4
  39. package/lib/checks/sql-snippets.js +4 -4
  40. package/lib/checks/types.js +7 -7
  41. package/lib/checks/utils.js +4 -4
  42. package/lib/checks/validator.js +16 -13
  43. package/lib/compiler/.eslintrc.json +1 -1
  44. package/lib/compiler/assert-consistency.js +0 -1
  45. package/lib/compiler/builtins.js +1 -1
  46. package/lib/compiler/checks.js +73 -15
  47. package/lib/compiler/define.js +3 -7
  48. package/lib/compiler/extend.js +212 -32
  49. package/lib/compiler/finalize-parse-cdl.js +7 -2
  50. package/lib/compiler/index.js +17 -14
  51. package/lib/compiler/populate.js +2 -5
  52. package/lib/compiler/propagator.js +2 -0
  53. package/lib/compiler/shared.js +23 -12
  54. package/lib/compiler/tweak-assocs.js +5 -6
  55. package/lib/compiler/utils.js +6 -0
  56. package/lib/edm/annotations/genericTranslation.js +553 -319
  57. package/lib/edm/annotations/preprocessAnnotations.js +39 -35
  58. package/lib/edm/csn2edm.js +88 -75
  59. package/lib/edm/edm.js +17 -3
  60. package/lib/edm/edmAnnoPreprocessor.js +5 -5
  61. package/lib/edm/edmPreprocessor.js +106 -76
  62. package/lib/edm/edmUtils.js +41 -2
  63. package/lib/gen/Dictionary.json +34 -0
  64. package/lib/gen/language.checksum +1 -1
  65. package/lib/gen/language.interp +66 -63
  66. package/lib/gen/language.tokens +81 -81
  67. package/lib/gen/languageLexer.interp +4 -10
  68. package/lib/gen/languageLexer.js +854 -869
  69. package/lib/gen/languageLexer.tokens +79 -81
  70. package/lib/gen/languageParser.js +14360 -14146
  71. package/lib/inspect/inspectModelStatistics.js +2 -2
  72. package/lib/inspect/inspectPropagation.js +6 -6
  73. package/lib/inspect/inspectUtils.js +2 -2
  74. package/lib/json/from-csn.js +82 -40
  75. package/lib/json/to-csn.js +82 -157
  76. package/lib/language/.eslintrc.json +1 -4
  77. package/lib/language/genericAntlrParser.js +59 -38
  78. package/lib/language/language.g4 +1508 -1490
  79. package/lib/language/multiLineStringParser.js +1 -1
  80. package/lib/main.js +3 -3
  81. package/lib/model/csnUtils.js +130 -122
  82. package/lib/model/revealInternalProperties.js +1 -1
  83. package/lib/model/sortViews.js +4 -6
  84. package/lib/modelCompare/utils/filter.js +4 -3
  85. package/lib/optionProcessor.js +5 -0
  86. package/lib/render/DuplicateChecker.js +1 -1
  87. package/lib/render/manageConstraints.js +12 -12
  88. package/lib/render/toCdl.js +225 -159
  89. package/lib/render/toHdbcds.js +63 -63
  90. package/lib/render/toRename.js +5 -5
  91. package/lib/render/toSql.js +55 -65
  92. package/lib/render/utils/common.js +20 -37
  93. package/lib/render/utils/delta.js +3 -3
  94. package/lib/render/utils/sql.js +22 -6
  95. package/lib/render/utils/stringEscapes.js +3 -3
  96. package/lib/transform/db/applyTransformations.js +3 -3
  97. package/lib/transform/db/assertUnique.js +13 -12
  98. package/lib/transform/db/associations.js +5 -5
  99. package/lib/transform/db/cdsPersistence.js +10 -8
  100. package/lib/transform/db/constraints.js +14 -14
  101. package/lib/transform/db/expansion.js +20 -22
  102. package/lib/transform/db/flattening.js +24 -42
  103. package/lib/transform/db/groupByOrderBy.js +3 -3
  104. package/lib/transform/db/temporal.js +6 -6
  105. package/lib/transform/db/transformExists.js +23 -23
  106. package/lib/transform/db/views.js +16 -16
  107. package/lib/transform/draft/db.js +10 -10
  108. package/lib/transform/draft/odata.js +2 -2
  109. package/lib/transform/forOdataNew.js +12 -40
  110. package/lib/transform/forRelationalDB.js +17 -7
  111. package/lib/transform/localized.js +2 -2
  112. package/lib/transform/odata/toFinalBaseType.js +41 -27
  113. package/lib/transform/odata/typesExposure.js +106 -62
  114. package/lib/transform/parseExpr.js +209 -106
  115. package/lib/transform/transformUtilsNew.js +2 -2
  116. package/lib/transform/translateAssocsToJoins.js +24 -19
  117. package/lib/transform/universalCsn/coreComputed.js +10 -10
  118. package/lib/transform/universalCsn/universalCsnEnricher.js +26 -26
  119. package/lib/transform/universalCsn/utils.js +3 -3
  120. package/lib/utils/file.js +5 -5
  121. package/lib/utils/moduleResolve.js +13 -13
  122. package/lib/utils/objectUtils.js +6 -6
  123. package/lib/utils/term.js +5 -2
  124. package/lib/utils/timetrace.js +51 -24
  125. package/package.json +5 -7
  126. package/share/messages/check-proper-type-of.md +1 -1
  127. package/share/messages/message-explanations.json +1 -1
  128. package/share/messages/redirected-to-complex.md +4 -4
  129. package/share/messages/{syntax-expecting-integer.md → syntax-expecting-unsigned-int.md} +7 -4
@@ -1,4 +1,4 @@
1
- 'use strict'
1
+ 'use strict';
2
2
 
3
3
  /**
4
4
  * Create a command line option processor and define valid commands, options and parameters.
@@ -46,7 +46,7 @@ function createOptionProcessor() {
46
46
  // TODO: Why exported?
47
47
  _parseCommandString,
48
48
  _parseOptionString,
49
- }
49
+ };
50
50
  return optionProcessor;
51
51
 
52
52
  /**
@@ -55,7 +55,7 @@ function createOptionProcessor() {
55
55
  * @param {string[]} [validValues] Array of valid values for the options.
56
56
  * @param {object} [options] Further options such as `ignoreCase: true`
57
57
  */
58
- function option(optString, validValues, options) {
58
+ function option( optString, validValues, options ) {
59
59
  return _addOption(optionProcessor, optString, validValues, options);
60
60
  }
61
61
 
@@ -63,7 +63,7 @@ function createOptionProcessor() {
63
63
  * API: Define the main help text (header and general options)
64
64
  * @param {string} text Help text describing all options, etc.
65
65
  */
66
- function help(text) {
66
+ function help( text ) {
67
67
  optionProcessor.helpText = text;
68
68
  return optionProcessor;
69
69
  }
@@ -72,7 +72,7 @@ function createOptionProcessor() {
72
72
  * API: Define a command
73
73
  * @param {string} cmdString Command name, short and long form, e.g. 'S, toSql'
74
74
  */
75
- function command(cmdString) {
75
+ function command( cmdString ) {
76
76
  /** @type {object} */
77
77
  const cmd = {
78
78
  options: {},
@@ -83,28 +83,28 @@ function createOptionProcessor() {
83
83
  return cmd;
84
84
  },
85
85
  help: commandHelp,
86
- ..._parseCommandString(cmdString)
86
+ ..._parseCommandString(cmdString),
87
87
  };
88
- if (optionProcessor.commands[cmd.longName]) {
89
- throw new Error(`Duplicate assignment for long command ${cmd.longName}`);
90
- }
88
+ if (optionProcessor.commands[cmd.longName])
89
+ throw new Error(`Duplicate assignment for long command ${ cmd.longName }`);
90
+
91
91
  optionProcessor.commands[cmd.longName] = cmd;
92
92
 
93
93
  if (cmd.shortName) {
94
- if (optionProcessor.commands[cmd.shortName]) {
95
- throw new Error(`Duplicate assignment for short command ${cmd.shortName}`);
96
- }
94
+ if (optionProcessor.commands[cmd.shortName])
95
+ throw new Error(`Duplicate assignment for short command ${ cmd.shortName }`);
96
+
97
97
  optionProcessor.commands[cmd.shortName] = cmd;
98
98
  }
99
99
  return cmd;
100
100
 
101
101
  // Command API: Define a command option
102
- function commandOption(optString, validValues, options) {
102
+ function commandOption( optString, validValues, options ) {
103
103
  return _addOption(cmd, optString, validValues, options);
104
104
  }
105
105
 
106
106
  // Command API: Define the command help text
107
- function commandHelp(text) {
107
+ function commandHelp( text ) {
108
108
  cmd.helpText = text;
109
109
  return cmd;
110
110
  }
@@ -120,29 +120,29 @@ function createOptionProcessor() {
120
120
  * @param {object[]} argList Array, to which the parsed arguments will be added. Default is global scope.
121
121
  * @private
122
122
  */
123
- function _setPositionalArguments(argumentDefinition, argList = optionProcessor.positionalArguments) {
124
- if (argList.find((arg) => arg.isDynamic)) {
125
- throw new Error(`Can't add positional arguments after a dynamic one`);
126
- }
123
+ function _setPositionalArguments( argumentDefinition, argList = optionProcessor.positionalArguments ) {
124
+ if (argList.find(arg => arg.isDynamic))
125
+ throw new Error('Can\'t add positional arguments after a dynamic one');
126
+
127
127
 
128
- const registeredNames = argList.map((arg) => arg.name);
128
+ const registeredNames = argList.map(arg => arg.name);
129
129
  const args = argumentDefinition.split(' ');
130
130
 
131
131
  for (const arg of args) {
132
132
  // Remove braces, dots and camelify.
133
133
  const argName = arg.replace('<', '').replace('>', '').replace('...', '').replace(/[ -]./g, s => s.substring(1).toUpperCase());
134
134
 
135
- if (registeredNames.includes(argName)) {
136
- throw new Error(`Duplicate positional argument: ${arg}`);
137
- }
138
- if (!isParam(arg) && !isDynamicPositionalArgument(arg)) {
139
- throw new Error(`Unknown positional argument syntax: ${arg}`)
140
- }
135
+ if (registeredNames.includes(argName))
136
+ throw new Error(`Duplicate positional argument: ${ arg }`);
137
+
138
+ if (!isParam(arg) && !isDynamicPositionalArgument(arg))
139
+ throw new Error(`Unknown positional argument syntax: ${ arg }`);
140
+
141
141
 
142
142
  argList.push({
143
143
  name: argName,
144
144
  isDynamic: isDynamicPositionalArgument(arg),
145
- required: true
145
+ required: true,
146
146
  });
147
147
 
148
148
  registeredNames.push(argName);
@@ -157,7 +157,7 @@ function createOptionProcessor() {
157
157
  * @private
158
158
  * @see option()
159
159
  */
160
- function _addOption(cmd, optString, validValues, options) {
160
+ function _addOption( cmd, optString, validValues, options ) {
161
161
  const cliOpt = _parseOptionString(optString, validValues);
162
162
  Object.assign(cliOpt, options);
163
163
  _addLongOption(cmd, cliOpt.longName, cliOpt);
@@ -180,14 +180,15 @@ function createOptionProcessor() {
180
180
  * @private
181
181
  * @see _addOption()
182
182
  */
183
- function _addLongOption(cmd, longName, opt) {
183
+ function _addLongOption( cmd, longName, opt ) {
184
184
  if (cmd.options[longName]) {
185
- throw new Error(`Duplicate assignment for long option ${longName}`);
186
- } else if (optionProcessor.options[longName]) {
185
+ throw new Error(`Duplicate assignment for long option ${ longName }`);
186
+ }
187
+ else if (optionProcessor.options[longName]) {
187
188
  // This path is only taken if optString is for commands
188
189
  optionProcessor.optionClashes.push({
189
190
  option: longName,
190
- description: `Command '${cmd.longName}' has option clash with general options for: ${longName}`
191
+ description: `Command '${ cmd.longName }' has option clash with general options for: ${ longName }`,
191
192
  });
192
193
  }
193
194
  cmd.options[longName] = opt;
@@ -201,16 +202,17 @@ function createOptionProcessor() {
201
202
  * @private
202
203
  * @see _addOption()
203
204
  */
204
- function _addShortOption(cmd, shortName, opt) {
205
+ function _addShortOption( cmd, shortName, opt ) {
205
206
  if (!shortName)
206
207
  return;
207
208
  if (cmd.options[shortName]) {
208
- throw new Error(`Duplicate assignment for short option ${shortName}`);
209
- } else if (optionProcessor.options[shortName]) {
209
+ throw new Error(`Duplicate assignment for short option ${ shortName }`);
210
+ }
211
+ else if (optionProcessor.options[shortName]) {
210
212
  // This path is only taken if optString is for commands
211
213
  optionProcessor.optionClashes.push({
212
214
  option: shortName,
213
- description: `Command '${cmd.longName}' has option clash with general options for: ${shortName}`
215
+ description: `Command '${ cmd.longName }' has option clash with general options for: ${ shortName }`,
214
216
  });
215
217
  }
216
218
  cmd.options[shortName] = opt;
@@ -221,7 +223,7 @@ function createOptionProcessor() {
221
223
  // longName: 'toFoo',
222
224
  // shortName: 'F',
223
225
  // }
224
- function _parseCommandString(cmdString) {
226
+ function _parseCommandString( cmdString ) {
225
227
  let longName;
226
228
  let shortName;
227
229
 
@@ -237,12 +239,12 @@ function createOptionProcessor() {
237
239
  longName = tokens[1];
238
240
  break;
239
241
  default:
240
- throw new Error(`Invalid command description: ${cmdString}`);
242
+ throw new Error(`Invalid command description: ${ cmdString }`);
241
243
  }
242
244
  return {
243
245
  longName,
244
246
  shortName,
245
- }
247
+ };
246
248
  }
247
249
 
248
250
  // Internal: Parse one option string like "-f, --foo-bar <p>". Returns an object like this
@@ -253,7 +255,7 @@ function createOptionProcessor() {
253
255
  // param: '<p>'
254
256
  // validValues
255
257
  // }
256
- function _parseOptionString(optString, validValues) {
258
+ function _parseOptionString( optString, validValues ) {
257
259
  let longName;
258
260
  let shortName;
259
261
  let param;
@@ -263,16 +265,17 @@ function createOptionProcessor() {
263
265
  switch (tokens.length) {
264
266
  case 1:
265
267
  // Must be "--foo"
266
- if (isLongOption(tokens[0])) {
268
+ if (isLongOption(tokens[0]))
267
269
  longName = tokens[0];
268
- }
270
+
269
271
  break;
270
272
  case 2:
271
273
  // Could be "--foo <bar>", or "-f --foo"
272
274
  if (isLongOption(tokens[0]) && isParam(tokens[1])) {
273
275
  longName = tokens[0];
274
276
  param = tokens[1];
275
- } else if (isShortOption(tokens[0]) && isLongOption(tokens[1])) {
277
+ }
278
+ else if (isShortOption(tokens[0]) && isLongOption(tokens[1])) {
276
279
  shortName = tokens[0];
277
280
  longName = tokens[1];
278
281
  }
@@ -286,18 +289,18 @@ function createOptionProcessor() {
286
289
  }
287
290
  break;
288
291
  default:
289
- throw new Error(`Invalid option description, too many tokens: ${optString}`);
290
- }
291
- if (!longName) {
292
- throw new Error(`Invalid option description, missing long name: ${optString}`);
293
- }
294
- if (!param && validValues) {
295
- throw new Error(`Option description has valid values but no param: ${optString}`);
292
+ throw new Error(`Invalid option description, too many tokens: ${ optString }`);
296
293
  }
294
+ if (!longName)
295
+ throw new Error(`Invalid option description, missing long name: ${ optString }`);
296
+
297
+ if (!param && validValues)
298
+ throw new Error(`Option description has valid values but no param: ${ optString }`);
299
+
297
300
  if (validValues) {
298
301
  validValues.forEach((value) => {
299
302
  if (typeof value !== 'string')
300
- throw new Error(`Valid values must be of type string: ${optString}`);
303
+ throw new Error(`Valid values must be of type string: ${ optString }`);
301
304
  });
302
305
  }
303
306
 
@@ -308,7 +311,7 @@ function createOptionProcessor() {
308
311
  param,
309
312
  validValues,
310
313
  isAlias: false, // default
311
- }
314
+ };
312
315
  }
313
316
 
314
317
  // API: Let the option processor digest a command line 'argv'
@@ -344,17 +347,17 @@ function createOptionProcessor() {
344
347
  // cmdErrors: [],
345
348
  // errors: [],
346
349
  // }
347
- function processCmdLine(argv) {
350
+ function processCmdLine( argv ) {
348
351
  const result = {
349
352
  command: undefined,
350
353
  options: { },
351
354
  unknownOptions: [],
352
355
  args: {
353
- length: 0
356
+ length: 0,
354
357
  },
355
358
  cmdErrors: [],
356
359
  errors: [],
357
- }
360
+ };
358
361
 
359
362
  // Iterate command line
360
363
  let seenDashDash = false;
@@ -363,7 +366,7 @@ function createOptionProcessor() {
363
366
  let arg = argv[i];
364
367
  // To be compatible with NPM arguments, we need to support `--arg=val` as well.
365
368
  if (arg.includes('=')) {
366
- argv = [ ...argv.slice(0, i), ...arg.split('='), ...argv.slice(i + 1)];
369
+ argv = [ ...argv.slice(0, i), ...arg.split('='), ...argv.slice(i + 1) ];
367
370
  arg = argv[i];
368
371
  }
369
372
 
@@ -385,30 +388,32 @@ function createOptionProcessor() {
385
388
  // Found as command
386
389
  result.command = optionProcessor.commands[arg].longName;
387
390
  result.options[result.command] = {};
388
- } else {
391
+ }
392
+ else {
389
393
  // Not found as command, take as arg and stop looking for commands
390
394
  processPositionalArgument(arg);
391
395
  result.command = null;
392
396
  }
393
- } else {
397
+ }
398
+ else {
394
399
  processPositionalArgument(arg);
395
400
  }
396
401
  }
397
402
  }
398
403
  // Avoid 'toXyz: {}' for command without options
399
- if (result.command && Object.keys(result.options[result.command]).length === 0) {
404
+ if (result.command && Object.keys(result.options[result.command]).length === 0)
400
405
  delete result.options[result.command];
401
- }
406
+
402
407
 
403
408
  // Complain about first missing positional arguments
404
- const missingArg = getCurrentPositionArguments().find((arg) => arg.required && !result.args[arg.name]);
409
+ const missingArg = getCurrentPositionArguments().find(arg => arg.required && !result.args[arg.name]);
405
410
  if (missingArg) {
406
411
  const forCommand = result.command ? ` for '${ result.command }'` : '';
407
- const errorMsg = `Missing positional argument${forCommand}: <${missingArg.name}${missingArg.isDynamic ? '...' : ''}>`;
412
+ const errorMsg = `Missing positional argument${ forCommand }: <${ missingArg.name }${ missingArg.isDynamic ? '...' : '' }>`;
408
413
  if (forCommand)
409
- result.cmdErrors.push(errorMsg)
414
+ result.cmdErrors.push(errorMsg);
410
415
  else
411
- result.errors.push(errorMsg)
416
+ result.errors.push(errorMsg);
412
417
  }
413
418
 
414
419
  return result;
@@ -424,7 +429,7 @@ function createOptionProcessor() {
424
429
  return ( cmd && cmd.positionalArguments && cmd.positionalArguments.length ) ? cmd.positionalArguments : optionProcessor.positionalArguments;
425
430
  }
426
431
 
427
- function processPositionalArgument(argumentValue) {
432
+ function processPositionalArgument( argumentValue ) {
428
433
  const argList = getCurrentPositionArguments();
429
434
  if ( result.args.length === 0 && argList.length === 0 )
430
435
  return;
@@ -433,16 +438,17 @@ function createOptionProcessor() {
433
438
  const nextUnsetArgument = argList[lastIndex];
434
439
  if (!inBounds && !nextUnsetArgument.isDynamic) {
435
440
  if (result.command)
436
- result.errors.push(`Too many arguments. '${result.command}' expects ${argList.length}`);
441
+ result.errors.push(`Too many arguments. '${ result.command }' expects ${ argList.length }`);
437
442
  else
438
- result.errors.push(`Too many arguments. Expected ${argList.length}`);
443
+ result.errors.push(`Too many arguments. Expected ${ argList.length }`);
439
444
  return;
440
445
  }
441
446
  result.args.length += 1;
442
447
  if (nextUnsetArgument.isDynamic) {
443
448
  result.args[nextUnsetArgument.name] = result.args[nextUnsetArgument.name] || [];
444
449
  result.args[nextUnsetArgument.name].push(argumentValue);
445
- } else {
450
+ }
451
+ else {
446
452
  result.args[nextUnsetArgument.name] = argumentValue;
447
453
  }
448
454
  }
@@ -452,7 +458,7 @@ function createOptionProcessor() {
452
458
  // Check the option definition to see if a parameter is expected.
453
459
  // If so, take it (complain if one is found in 'argv').
454
460
  // Populate 'result.options' with the result. Return the number params found (0 or 1).
455
- function processOption(i) {
461
+ function processOption( i ) {
456
462
  const arg = argv[i];
457
463
  let currentCommand = result.command;
458
464
 
@@ -491,18 +497,17 @@ function createOptionProcessor() {
491
497
  */
492
498
  function reportUnknown() {
493
499
  if (currentCommand)
494
- result.unknownOptions.push(`Unknown option "${arg}" for the command "${currentCommand}"`);
500
+ result.unknownOptions.push(`Unknown option "${ arg }" for the command "${ currentCommand }"`);
495
501
  else
496
- result.unknownOptions.push(`Unknown option "${arg}"`);
502
+ result.unknownOptions.push(`Unknown option "${ arg }"`);
497
503
 
498
504
  if (currentCommand) {
499
505
  // Not found at all. We dig into the other cdsc commands in order to check if
500
506
  // the option expects a parameter and if so to take the next argument as a value
501
507
  const otherCmd = Object.keys(optionProcessor.commands).find(cmd => optionProcessor.commands[cmd].options[arg]);
502
508
  const otherCmdOpt = otherCmd && optionProcessor.commands[otherCmd].options[arg];
503
- if (otherCmdOpt && hasParamForUnknown(otherCmdOpt)) {
504
- return 1
505
- }
509
+ if (otherCmdOpt && hasParamForUnknown(otherCmdOpt))
510
+ return 1;
506
511
  }
507
512
 
508
513
  if (hasParamForUnknown(null))
@@ -511,7 +516,7 @@ function createOptionProcessor() {
511
516
  return 0;
512
517
  }
513
518
 
514
- function setCurrentOption(val) {
519
+ function setCurrentOption( val ) {
515
520
  if (currentCommand) {
516
521
  if (!result.options[currentCommand])
517
522
  result.options[currentCommand] = {};
@@ -522,20 +527,22 @@ function createOptionProcessor() {
522
527
  }
523
528
  }
524
529
 
525
- function reportMissingParam(opt) {
526
- let error = `Missing param "${opt.param}" for option "${opt.shortName ? opt.shortName + ', ': ''}${opt.longName}"`;
530
+ function reportMissingParam( opt ) {
531
+ const short = opt.shortName ? `${ opt.shortName }, ` : '';
532
+ let error = `Missing param "${ opt.param }" for option "${ short }${ opt.longName }"`;
527
533
  if (currentCommand) {
528
- error = `${error} of command "${currentCommand}"`;
534
+ error = `${ error } of command "${ currentCommand }"`;
529
535
  result.cmdErrors.push(error);
530
- } else {
536
+ }
537
+ else {
531
538
  result.errors.push(error);
532
539
  }
533
540
  }
534
541
 
535
- function reportInvalidValue(opt, value) {
536
- const shortOption = opt.shortName ? `${opt.shortName}, ` : ''
542
+ function reportInvalidValue( opt, value ) {
543
+ const shortOption = opt.shortName ? `${ opt.shortName }, ` : '';
537
544
  const errors = currentCommand ? result.cmdErrors : result.errors;
538
- errors.push(`Invalid value "${value}" for option "${shortOption}${opt.longName}" - use one of [${opt.validValues}]`);
545
+ errors.push(`Invalid value "${ value }" for option "${ shortOption }${ opt.longName }" - use one of [${ opt.validValues }]`);
539
546
  }
540
547
 
541
548
  /**
@@ -544,17 +551,17 @@ function createOptionProcessor() {
544
551
  *
545
552
  * @returns {null|*}
546
553
  */
547
- function paramForOption(opt, reportMissing = true) {
554
+ function paramForOption( opt, reportMissing = true ) {
548
555
  if (i + 1 >= argv.length || argv[i + 1].startsWith('-')) {
549
556
  if (reportMissing)
550
- reportMissingParam(opt)
557
+ reportMissingParam(opt);
551
558
  return null;
552
559
  }
553
560
 
554
561
  const value = argv[i + 1];
555
- if (!isValidOptionValue(opt, value) && reportMissing) {
562
+ if (!isValidOptionValue(opt, value) && reportMissing)
556
563
  reportInvalidValue(opt, value);
557
- }
564
+
558
565
  return value;
559
566
  }
560
567
 
@@ -567,7 +574,7 @@ function createOptionProcessor() {
567
574
  * @param {object|null} opt
568
575
  * @returns {boolean}
569
576
  */
570
- function hasParamForUnknown(opt) {
577
+ function hasParamForUnknown( opt ) {
571
578
  return ((!opt || opt.param) && (i + 1) < argv.length && !argv[i + 1].match('(^[.-])|[.](csn|cdl|cds|json)$'));
572
579
  }
573
580
  }
@@ -577,40 +584,40 @@ function createOptionProcessor() {
577
584
  // If 'command' is supplied, check only 'options.command', otherwise check
578
585
  // only top-level options
579
586
  // Return an array of complaints (possibly empty)
580
- function verifyOptions(options, commandName = undefined, silent = false) {
587
+ function verifyOptions( options, commandName = undefined, silent = false ) {
581
588
  const result = [];
582
589
  let opts;
583
590
 
584
591
  if ((options.betaMode || options.beta) && !options.testMode && !silent) {
585
592
  const mode = options.beta ? 'beta' : 'beta-mode';
586
- result.push(`Option --${mode} was used. This option should not be used in productive scenarios!`)
593
+ result.push(`Option --${ mode } was used. This option should not be used in productive scenarios!`);
587
594
  }
588
595
 
589
596
  if (options) {
590
597
  [
591
598
  'defaultBinaryLength', 'defaultStringLength',
592
- /*'length', 'precision', 'scale'*/
593
- ].forEach(facet => {
594
- if(options[facet] && isNaN(options[facet])) {
595
- result.push(`Invalid value "${options[facet]}" for option "--${facet}" - not an Integer`);
596
- } else {
599
+ /* 'length', 'precision', 'scale' */
600
+ ].forEach((facet) => {
601
+ if (options[facet] && isNaN(options[facet]))
602
+ result.push(`Invalid value "${ options[facet] }" for option "--${ facet }" - not an Integer`);
603
+ else
597
604
  options[facet] = parseInt(options[facet]);
598
- }
599
605
  });
600
606
  }
601
607
 
602
608
  if (commandName) {
603
609
  const cmd = optionProcessor.commands[commandName];
604
- if (!cmd) {
605
- throw new Error(`Expected existing command: "${cmd}"`);
606
- }
610
+ if (!cmd)
611
+ throw new Error(`Expected existing command: "${ cmd }"`);
612
+
607
613
  opts = cmd.options;
608
614
  options = options[cmd] || {};
609
615
  if (typeof options === 'boolean') {
610
616
  // Special case: command without options
611
617
  options = {};
612
618
  }
613
- } else {
619
+ }
620
+ else {
614
621
  opts = optionProcessor.options;
615
622
  }
616
623
  // Look at each supplied option
@@ -620,42 +627,43 @@ function createOptionProcessor() {
620
627
  if (!opt) {
621
628
  // Don't report commands in top-level options
622
629
  if ((commandName || !optionProcessor.commands[camelName]) && !silent) {
623
- error = `Unknown option "${commandName ? commandName + '.' : ''}${camelName}"`;
630
+ const prefix = commandName ? `${commandName}.` : '';
631
+ error = `Unknown option "${prefix}${camelName}"`;
624
632
  }
625
- } else {
633
+ }
634
+ else {
626
635
  const param = options[camelName];
627
- error = verifyOptionParam(param, opt, commandName ? commandName + '.' : '');
636
+ error = verifyOptionParam(param, opt, commandName ? `${ commandName }.` : '');
628
637
  }
629
- if (error) {
638
+ if (error)
630
639
  result.push(error);
631
- }
632
640
  }
633
641
  // hard-coded option dependencies (they disappear with command)
634
642
  return result;
635
643
 
636
644
  // Verify parameter value 'param' against option definition 'opt'. Return an error
637
645
  // string or false for an accepted param. Use 'prefix' when mentioning the option name.
638
- function verifyOptionParam(param, opt, prefix) {
646
+ function verifyOptionParam( param, opt, prefix ) {
639
647
  if (opt.param) {
640
648
  // Parameter is required for this option
641
- if (typeof param === 'boolean') {
642
- return `Missing value for option "${prefix}${opt.camelName}"`;
643
- } else if (!isValidOptionValue(opt, param)) {
644
- return `Invalid value "${param}" for option "${prefix}${opt.camelName}" - use one of [${opt.validValues}]`;
645
- }
649
+ if (typeof param === 'boolean')
650
+ return `Missing value for option "${ prefix }${ opt.camelName }"`;
651
+ else if (!isValidOptionValue(opt, param))
652
+ return `Invalid value "${ param }" for option "${ prefix }${ opt.camelName }" - use one of [${ opt.validValues }]`;
653
+
646
654
  return false;
647
- } else {
648
- // Option does not expect a parameter
649
- if (typeof param !== 'boolean') {
650
- // FIXME: Might be a bit too strict in case of internal sub-options like 'forHana' etc...
651
- return `Expecting boolean value for option "${prefix}${opt.camelName}"`;
652
- }
653
655
  }
656
+ // Option does not expect a parameter
657
+ if (typeof param !== 'boolean') {
658
+ // FIXME: Might be a bit too strict in case of internal sub-options like 'forHana' etc...
659
+ return `Expecting boolean value for option "${ prefix }${ opt.camelName }"`;
660
+ }
661
+
654
662
  return false;
655
663
  }
656
664
  }
657
665
 
658
- function isValidOptionValue(opt, value) {
666
+ function isValidOptionValue( opt, value ) {
659
667
  // Explicitly convert to string, input 'value' may be boolean
660
668
  value = String(value);
661
669
  if (!opt.validValues || !opt.validValues.length)
@@ -667,12 +675,12 @@ function createOptionProcessor() {
667
675
 
668
676
  // Return an array of unique camelNames of the options for the specified command
669
677
  // If invalid command -> an empty array
670
- function camelOptionsForCommand(cmd) {
678
+ function camelOptionsForCommand( cmd ) {
671
679
  if (!cmd || !optionProcessor.commands[cmd])
672
- return []
680
+ return [];
673
681
  cmd = optionProcessor.commands[cmd];
674
682
  const names = Object.keys(cmd.options).map(name => cmd.options[name].camelName);
675
- return [...new Set(names)];
683
+ return [ ...new Set(names) ];
676
684
  }
677
685
  }
678
686
 
@@ -682,54 +690,55 @@ function createOptionProcessor() {
682
690
  * @param {string[]} argv Argument array
683
691
  * @param {number} i Current option index.
684
692
  */
685
- function splitSingleLetterOption(argv, i) {
693
+ function splitSingleLetterOption( argv, i ) {
686
694
  const arg = argv[i];
687
695
  if (arg.length > 2) { // must be at least `-ab`.
688
696
  const rest = argv.slice(i + 1);
689
697
  argv.length = i; // trim array
690
- argv.push(...arg.split('').slice(1).map(a => `-${a}`), ...rest);
698
+ argv.push(...arg.split('').slice(1).map(a => `-${ a }`), ...rest);
691
699
  }
692
700
  }
693
701
 
694
702
  /**
695
703
  * Return a camelCase name "fooBar" for a long option "--foo-bar"
696
704
  */
697
- function camelifyLongOption(opt) {
705
+ function camelifyLongOption( opt ) {
698
706
  return opt.substring(2).replace(/-./g, s => s.substring(1).toUpperCase());
699
707
  }
700
708
 
701
709
  /**
702
710
  * Return a long option name like "--foo-bar" for a camel-case name "fooBar"
703
711
  */
704
- function uncamelifyLongOption(opt) {
705
- return `--${opt.replace(/[A-Z]/g, s => '-' + s.toLowerCase())}`;
712
+ function uncamelifyLongOption( opt ) {
713
+ const longForm = opt.replace(/[A-Z]/g, s => `-${ s.toLowerCase() }`);
714
+ return `--${ longForm }`;
706
715
  }
707
716
 
708
717
  /**
709
718
  * Check if 'opt' looks like a "-f" short option
710
719
  */
711
- function isShortOption(opt) {
720
+ function isShortOption( opt ) {
712
721
  return /^-[a-zA-Z?]$/.test(opt);
713
722
  }
714
723
 
715
724
  /**
716
725
  * Check if 'opt' looks like a "--foo-bar" long option
717
726
  */
718
- function isLongOption(opt) {
727
+ function isLongOption( opt ) {
719
728
  return /^--[a-zA-Z0-9-]+$/.test(opt);
720
729
  }
721
730
 
722
731
  /**
723
732
  * Check if 'opt' looks like a "<foobar>" parameter
724
733
  */
725
- function isParam(opt) {
734
+ function isParam( opt ) {
726
735
  return /^<[a-zA-Z-]+>$/.test(opt);
727
736
  }
728
737
 
729
738
  /**
730
739
  * Check if 'arg' looks like "<foobar...>"
731
740
  */
732
- function isDynamicPositionalArgument(arg) {
741
+ function isDynamicPositionalArgument( arg ) {
733
742
  return /^<[a-zA-Z-]+[.]{3}>$/.test(arg);
734
743
  }
735
744
 
@@ -738,5 +747,5 @@ module.exports = {
738
747
  isShortOption,
739
748
  isLongOption,
740
749
  isParam,
741
- isDynamicPositionalArgument
750
+ isDynamicPositionalArgument,
742
751
  };