@sap/cds-compiler 5.8.2 → 5.9.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 (87) hide show
  1. package/CHANGELOG.md +38 -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 +16 -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/parseExpr.js +2 -2
  79. package/lib/transform/transformUtils.js +9 -7
  80. package/lib/transform/translateAssocsToJoins.js +0 -2
  81. package/lib/transform/universalCsn/coreComputed.js +2 -2
  82. package/lib/utils/moduleResolve.js +7 -5
  83. package/package.json +1 -1
  84. package/share/messages/def-upcoming-virtual-change.md +55 -0
  85. package/share/messages/file-unexpected-case-mismatch.md +61 -0
  86. package/share/messages/message-explanations.json +2 -0
  87. package/lib/transform/braceExpression.js +0 -77
@@ -1925,7 +1925,7 @@ function onlyWith( spec, need, csn, prop, xor, expected ) {
1925
1925
 
1926
1926
  /**
1927
1927
  * @param {string[]} groups
1928
- * @param {string} exception
1928
+ * @param {string|Function} exception
1929
1929
  * @param {string} prop
1930
1930
  * @param {object} xor
1931
1931
  * @return {boolean}
@@ -780,6 +780,8 @@ function addOrigin( csn, xsn, node ) {
780
780
  }
781
781
  else if (xsn.includes) {
782
782
  csn.$origin = includesOrigin( xsn.includes, xsn );
783
+ if (xsn.$inferred === 'composition-entity' || xsn.$inferred === 'localized-entity')
784
+ inferredPropertiesForOrigin( csn, node );
783
785
  return;
784
786
  }
785
787
  let origin = getOrigin( node );
@@ -1170,7 +1172,13 @@ function enumValueOrCalc( v, csn, node ) {
1170
1172
  if (node.kind === 'enum') {
1171
1173
  Object.assign( csn, expression( v ) );
1172
1174
  }
1173
- else if (node.$syntax === 'calc' || node._parent?.kind === 'extend') {
1175
+ // In XSN, there are combined elem/column objects: do not represent column
1176
+ // expression when presented as element in CSN
1177
+
1178
+ // node.$syntax set in define.el(!), but not inside an `extend`, a _parent might
1179
+ // not be set always for parse-only, especially with CSN input
1180
+ else if (node.$syntax === 'calc' ||
1181
+ !node._parent || node._parent.kind === 'extend') {
1174
1182
  const stored = v.stored ? { stored: value(v.stored) } : {};
1175
1183
  return Object.assign( stored, expression( v ) );
1176
1184
  }
@@ -1275,12 +1283,31 @@ function exprInternal( node, xprParens ) {
1275
1283
  return rargs.length === 1 ? rargs[0] : flattenInternalXpr( rargs, val );
1276
1284
  }
1277
1285
 
1278
- function flattenInternalXpr( array, op ) {
1286
+
1287
+ const naryOperators = {
1288
+ __proto__: null,
1289
+ // not '.'
1290
+ '*': true,
1291
+ '/': true,
1292
+ '+': true,
1293
+ '-': true,
1294
+ '||': true,
1295
+ and: true,
1296
+ or: true,
1297
+ };
1298
+
1299
+ function flattenInternalXpr( array, xprOp ) {
1279
1300
  if (!structXpr)
1280
1301
  return array.flat( Infinity );
1281
1302
  // TODO: do not rely on 'nary' - this dosn't work with CSN input have an
1282
1303
  // `xpr: [{val:1},'+',{val:2},'+',{val:3}]`.
1283
- if (array.length < 5 || op !== 'nary')
1304
+ const { length } = array;
1305
+ if (length < 5 || length % 2 === 0)
1306
+ return array;
1307
+ const op = array[1];
1308
+ if (typeof op !== 'string' || !naryOperators[op] ||
1309
+ xprOp !== 'nary' && // for old CDL parser
1310
+ array.some( ( item, idx ) => item !== op && idx % 2 === 1 ))
1284
1311
  return array;
1285
1312
  // nary: [ ‹a›, '+', ‹b›, '+', ‹c› ] → [ [ ‹a›, '+', ‹b› ], '+', ‹c› ]
1286
1313
  let left = array.slice( 0, 3 );
@@ -102,6 +102,7 @@ Object.assign(GenericAntlrParser.prototype, {
102
102
  fragileAlias,
103
103
  identAst,
104
104
  reportPathNamedManyOrOne,
105
+ reportVirtualAsRef,
105
106
  reportMissingSemicolon,
106
107
  pushXprToken,
107
108
  pushOpToken,
@@ -812,6 +813,21 @@ function reportPathNamedManyOrOne( { path } ) {
812
813
  }
813
814
  }
814
815
 
816
+ function reportVirtualAsRef() {
817
+ const { type, text } = this._input.LT(2);
818
+ if (this.constructor.Number < type && type <= this.constructor.Identifier ||
819
+ [ '+', '-', '(' ].includes( text )) {
820
+ // remark: we do not need to include 'not', as condition operators are only
821
+ // allowed inside parentheses in the old parser
822
+ const token = this._input.LT(1);
823
+ this.message( 'syntax-deprecated-ref-virtual', token, {
824
+ '#': (text === '(' ? 'func' : 'ref'),
825
+ name: token.text,
826
+ delimited: token.text,
827
+ } );
828
+ }
829
+ }
830
+
815
831
  function reportMissingSemicolon() {
816
832
  const next = this._input.LT(1);
817
833
  if (next.text !== ';' && next.text !== '' && // ';' by insertSemicolon()
package/lib/main.d.ts CHANGED
@@ -135,6 +135,15 @@ declare namespace compiler {
135
135
  * @since v2.8.0
136
136
  */
137
137
  addTextsLanguageAssoc?: boolean
138
+ /**
139
+ * If set to `true`, add named aspects to the list of 'includes' of the generated entity.
140
+ * This will cause propagation of actions from aspect to generated entity.
141
+ *
142
+ * Will become default in v6.
143
+ *
144
+ * @since v5.9.0
145
+ */
146
+ compositionIncludes?: boolean
138
147
  /**
139
148
  * An array of directory names that are used for CDS module lookups.
140
149
  * Lookup directory `node_modules/` is appended if not set explicitly.
@@ -435,6 +444,22 @@ declare namespace compiler {
435
444
  * @beta
436
445
  */
437
446
  betterSqliteSessionVariables?: boolean
447
+ /**
448
+ * If set, operator `!=` will be treated as a boolean-logic operator,
449
+ * instead of a three-valued operator, by rendering it as `IS DISTINCT FROM`
450
+ * on databases that support it, or an equivalent expression.
451
+ *
452
+ * Note, that if disabled:
453
+ * - `!=`, is not translated and is hence treated as `<>`, meaning it uses
454
+ * three-valued logic, on databases that support it.
455
+ * - `==` is still treated as two-valued logic operator.
456
+ *
457
+ * This option will become the default in cds-compiler v6.
458
+ *
459
+ * @since 5.9.0
460
+ * @default false
461
+ */
462
+ booleanEquality?: boolean
438
463
  }
439
464
 
440
465
  /**
@@ -519,7 +544,52 @@ declare namespace compiler {
519
544
  * @note `to.cdl()` currently has no specific options.
520
545
  * @see to.cdl()
521
546
  */
522
- export interface CdlOptions extends Options {}
547
+ export interface CdlOptions extends Options {
548
+ /**
549
+ * If `true`, to.cdl() nests rendered definitions, e.g. all service/context entities
550
+ * are nested inside a service/context definition.
551
+ * This shortens definition names, as instead of `entity a.b.c.d.E {…}`,
552
+ * a `service a.b.c.d {…}` with inner `entity E {…}` is rendered.
553
+ * May introduce additional USING statements for paths that can't be reached
554
+ * without one inside the current scope, e.g. when paths are shadowed in inner scopes.
555
+ *
556
+ * __Example__ (also using `renderCdlCommonNamespace: true`):
557
+ *
558
+ * ```cds
559
+ * namespace S;
560
+ * using { S as S_ };
561
+ * entity Base {
562
+ * key id : String;
563
+ * };
564
+ * service S {
565
+ * entity Base as projection on S_.Base as Base;
566
+ * };
567
+ * ```
568
+ *
569
+ * If `false`, there is no nesting of definitions inside services or contexts.
570
+ * All definitions are defined using their fully qualified path.
571
+ *
572
+ * __Example__:
573
+ *
574
+ * ```cds
575
+ * entity S.Base {
576
+ * key id : String;
577
+ * };
578
+ * service S.S {};
579
+ * entity S.S.Base as projection on S.Base as Base;
580
+ * ```
581
+ *
582
+ * @default false
583
+ */
584
+ renderCdlDefinitionNesting?: boolean
585
+ /**
586
+ * If `true`, `to.cdl()` tries to extract a common namespace that is then rendered
587
+ * as a `namespace` statement.
588
+ *
589
+ * Only usable in combination with `renderCdlDefinitionNesting: true`.
590
+ */
591
+ renderCdlCommonNamespace?: boolean
592
+ }
523
593
 
524
594
  /**
525
595
  * The compiler's package version.
@@ -925,6 +995,14 @@ declare namespace compiler {
925
995
  * @internal
926
996
  */
927
997
  function seal(csn: CSN, options?: EffectiveCsnOptions): CSN;
998
+ /**
999
+ * Transform the given (inferred/client) CSN into one that is used by the
1000
+ * CAP Java runtime. The CSN is structured.
1001
+ * Changes include draft handling and the tenant discriminator if requested.
1002
+ *
1003
+ * @internal
1004
+ */
1005
+ function java(csn: CSN, options?: ODataOptions): CSN;
928
1006
  }
929
1007
 
930
1008
  export { _for as for };
@@ -269,6 +269,7 @@ function csnRefs( csn, universalReady ) {
269
269
  effectiveType,
270
270
  artifactRef,
271
271
  getOrigin,
272
+ queryForElements,
272
273
  inspectRef,
273
274
  queryOrMain,
274
275
  getColumn: elem => getCache( elem, '_column' ),
@@ -484,6 +485,10 @@ function csnRefs( csn, universalReady ) {
484
485
  return art;
485
486
  }
486
487
 
488
+ function queryForElements( query ) {
489
+ return query && cache.get( query.projection || query );
490
+ }
491
+
487
492
  function initDefinition( main ) {
488
493
  const name = typeof main === 'string' && main;
489
494
  if (name) {
@@ -753,6 +758,7 @@ function csnRefs( csn, universalReady ) {
753
758
  function msgLocations( csnPath ) {
754
759
  let location = csn?.$location;
755
760
  const artifact = new SemanticLocation();
761
+ /** @type object */
756
762
  let obj = csn;
757
763
  let index = 0;
758
764
  let inlinePathIndex = null;
@@ -1076,7 +1082,7 @@ function traverseFrom( from, fromSelect, parentQuery, callback ) {
1076
1082
  else if (from.args) { // join
1077
1083
  from.args.forEach( arg => traverseFrom( arg, fromSelect, parentQuery, callback ) );
1078
1084
  if (from.on) // join-on, potentially having a sub query (in xpr)
1079
- from.on.forEach(arg => traverseExpr(arg, fromSelect, callback));
1085
+ from.on.forEach(arg => traverseExpr( arg, fromSelect, callback ));
1080
1086
  }
1081
1087
  else { // sub query in FROM
1082
1088
  traverseQuery( from, fromSelect, parentQuery, callback );
@@ -1148,8 +1154,9 @@ function pathId( item ) {
1148
1154
  }
1149
1155
 
1150
1156
  function implicitAs( ref ) {
1151
- const item = ref[ref.length - 1];
1152
- const id = (typeof item === 'string') ? item : item.id; // inlined `pathId`
1157
+ if (typeof ref !== 'string')
1158
+ ref = ref[ref.length - 1];
1159
+ const id = (typeof ref === 'string') ? ref : ref.id; // inlined `pathId`
1153
1160
  return id.substring( id.lastIndexOf('.') + 1 );
1154
1161
  }
1155
1162
 
@@ -1282,7 +1289,7 @@ function analyseCsnPath( csnPath, csn, resolve ) {
1282
1289
  else if (prop === 'orderBy') {
1283
1290
  refCtx = 'orderBy';
1284
1291
  }
1285
- else if (prop.charAt(0) === '@') {
1292
+ else if (prop[0] === '@') {
1286
1293
  refCtx = 'annotation';
1287
1294
  }
1288
1295
  else if (prop !== 'xpr' && prop !== 'list') {
@@ -1314,7 +1321,7 @@ function isSelectQuery( query ) {
1314
1321
  * If the column is an expression without explicit alias, `false` is returned.
1315
1322
  * Use csnRefs.getColumnName() instead.
1316
1323
  *
1317
- * @returns {string|false}
1324
+ * @returns {string}
1318
1325
  */
1319
1326
  function columnAlias( col ) {
1320
1327
  return col.as || (!col.args && col.func) || (col.ref && implicitAs( col.ref ));
@@ -0,0 +1,71 @@
1
+ // Create a hierarchical expression tree from an `xpr` array
2
+ //
3
+ // Replace `xpr` arrays and conditions by precedence-aware tree representations.
4
+ // The transformation is deep and destructive.
5
+ //
6
+ // Queries in expressions are _not_ traversed.
7
+ //
8
+ // Function/assoc arguments and filter conditions are
9
+ // - traversed with expressionAsTree() and conditionAsTree(),
10
+ // - not traversed with exprAsTree() and condAsTree()
11
+
12
+ 'use strict';
13
+
14
+ const xprParser = require( '../parsers/XprTree' );
15
+
16
+ function conditionAsTree( args ) {
17
+ args.forEach( expressionAsTree );
18
+ return xprParser.xprAsTree( args, args, true );
19
+ }
20
+ function condAsTree( args ) {
21
+ args.forEach( exprAsTree );
22
+ return xprParser.xprAsTree( args, args, true );
23
+ }
24
+
25
+ function expressionAsTree( expr ) {
26
+ if (!expr || typeof expr !== 'object')
27
+ return expr;
28
+ if (Array.isArray( expr )) { // hierarchical input
29
+ // expr.forEach( expressionAsTree ); // do it again?
30
+ return expr;
31
+ }
32
+ if (expr.list) // expression, ref
33
+ expr.list.forEach( expressionAsTree );
34
+ if (expr.args) { // expression, ref
35
+ if (Array.isArray( expr.args ) )
36
+ expr.args.forEach(expressionAsTree);
37
+ else
38
+ Object.values(expr.args).forEach(expressionAsTree);
39
+ }
40
+ if (expr.ref) // expression
41
+ expr.ref.forEach( expressionAsTree );
42
+
43
+ // conditions: change properties
44
+ if (expr.xpr) // expression
45
+ expr.xpr = conditionAsTree( expr.xpr );
46
+ if (expr.where) // ref or query
47
+ expr.where = conditionAsTree( expr.where );
48
+
49
+ return expr;
50
+ }
51
+ function exprAsTree( expr ) {
52
+ if (!expr || typeof expr !== 'object')
53
+ return expr;
54
+ if (Array.isArray( expr )) { // hierarchical input
55
+ // expr.forEach( exprAsTree ); // do it again?
56
+ return expr;
57
+ }
58
+ if (expr.list) // expression, ref
59
+ expr.list.forEach( exprAsTree );
60
+ // conditions: change properties
61
+ if (expr.xpr) // expression
62
+ expr.xpr = condAsTree( expr.xpr );
63
+ return expr;
64
+ }
65
+
66
+ module.exports = {
67
+ conditionAsTree,
68
+ condAsTree,
69
+ expressionAsTree,
70
+ exprAsTree,
71
+ };
@@ -223,7 +223,7 @@ const details = {
223
223
 
224
224
  function getDetails(id, name) {
225
225
  if (details[id])
226
- return `${details[id] } "${ name }" - check warnings for details`;
226
+ return `${ details[id] } "${ name }" - check warnings for details`;
227
227
 
228
228
  return null;
229
229
  }
@@ -1,5 +1,7 @@
1
1
  // Compiler options
2
2
 
3
+ /* eslint @stylistic/js/max-len: 0 */
4
+
3
5
  // Remarks:
4
6
  // - The specification is client-tool centric (bin/cdsc.js):
5
7
  // an option named `fooBar` is “produced” by `.option(' --foo-bar')`.
@@ -21,13 +23,13 @@ optionProcessor
21
23
  .option('-h, --help')
22
24
  .option('-v, --version')
23
25
  .option(' --options <file>')
24
- .option('-w, --warning <level>', { valid: ['0', '1', '2', '3'] })
26
+ .option('-w, --warning <level>', { valid: [ '0', '1', '2', '3' ] })
25
27
  .option(' --quiet')
26
28
  .option('-i, --stdin')
27
29
  .option(' --show-message-id')
28
30
  .option(' --no-message-id')
29
31
  .option(' --no-message-context')
30
- .option(' --color <mode>', { valid: ['auto', 'always', 'never'] })
32
+ .option(' --color <mode>', { valid: [ 'auto', 'always', 'never' ] })
31
33
  .option('-o, --out <dir>')
32
34
  .option(' --cds-home <dir>')
33
35
  .option(' --module-lookup-directories <list>')
@@ -52,8 +54,10 @@ optionProcessor
52
54
  .option(' --add-texts-language-assoc')
53
55
  .option(' --localized-without-coalesce')
54
56
  .option(' --tenant-discriminator')
57
+ .option(' --no-composition-includes')
55
58
  .option(' --default-binary-length <length>')
56
59
  .option(' --default-string-length <length>')
60
+ .option(' --struct-xpr')
57
61
  .option(' --no-recompile')
58
62
  .option(' --skip-name-check', { optionName: '$skipNameCheck' })
59
63
  .positionalArgument('<files...>')
@@ -120,11 +124,11 @@ optionProcessor
120
124
  --beta <list> Comma separated list of unsupported, incomplete (beta) features to use.
121
125
  Valid values are:
122
126
  ${
123
- Object.keys(availableBetaFlags)
124
- .filter(flag => availableBetaFlags[flag])
125
- .sort()
126
- .join('\n' + ' '.repeat(30))
127
- }
127
+ Object.keys(availableBetaFlags)
128
+ .filter(flag => availableBetaFlags[flag])
129
+ .sort()
130
+ .join(`\n${ ' '.repeat(30) }`)
131
+ }
128
132
  --deprecated <list> Comma separated list of deprecated options.
129
133
  Valid values are:
130
134
  eagerPersistenceForGeneratedEntities
@@ -152,7 +156,10 @@ optionProcessor
152
156
  --add-texts-language-assoc In generated texts entities, add association "language"
153
157
  to "sap.common.Languages" if it exists
154
158
  --localized-without-coalesce Omit coalesce in localized convenience views
159
+ --no-composition-includes Do NOT add named aspects to 'includes' property of generated composition entity.
155
160
  --no-recompile Don't recompile in case of internal errors
161
+ --struct-xpr Write structured expressions to the compiler CSN output (possibly then
162
+ used as input for backends)
156
163
  --skip-name-check Skip certain name checks, e.g. that there must be no '.' in element names.
157
164
 
158
165
  Commands
@@ -185,7 +192,7 @@ optionProcessor
185
192
  // ----------- toHana -----------
186
193
  optionProcessor.command('H, toHana')
187
194
  .option('-h, --help')
188
- .option('-n, --sql-mapping <style>', { valid: ['plain', 'quoted', 'hdbcds'], aliases: ['--names'] })
195
+ .option('-n, --sql-mapping <style>', { valid: [ 'plain', 'quoted', 'hdbcds' ], aliases: [ '--names' ] })
189
196
  .option(' --render-virtual')
190
197
  .option(' --joinfk')
191
198
  .option('-u, --user <user>')
@@ -193,8 +200,8 @@ optionProcessor.command('H, toHana')
193
200
  .option('-c, --csn')
194
201
  .option(' --integrity-not-validated')
195
202
  .option(' --integrity-not-enforced')
196
- .option(' --assert-integrity <mode>', { valid: ['true', 'false', 'individual'] })
197
- .option(' --assert-integrity-type <type>', { valid: ['RT', 'DB'], ignoreCase: true })
203
+ .option(' --assert-integrity <mode>', { valid: [ 'true', 'false', 'individual' ] })
204
+ .option(' --assert-integrity-type <type>', { valid: [ 'RT', 'DB' ], ignoreCase: true })
198
205
  .option(' --pre2134ReferentialConstraintNames')
199
206
  .option(' --disable-hana-comments')
200
207
  .option(' --standard-database-functions')
@@ -239,7 +246,7 @@ optionProcessor.command('H, toHana')
239
246
 
240
247
  optionProcessor.command('O, toOdata')
241
248
  .option('-h, --help')
242
- .option('-v, --odata-version <version>', { valid: ['v2', 'v4', 'v4x'], aliases: ['--version'] })
249
+ .option('-v, --odata-version <version>', { valid: [ 'v2', 'v4', 'v4x' ], aliases: [ '--version' ] })
243
250
  .option('-x, --xml')
244
251
  .option('-j, --json')
245
252
  .option(' --odata-containment')
@@ -253,8 +260,8 @@ optionProcessor.command('O, toOdata')
253
260
  .option(' --odata-vocabularies <list>')
254
261
  .option(' --odata-no-creator')
255
262
  .option('-c, --csn')
256
- .option('-f, --odata-format <format>', { valid: ['flat', 'structured'] })
257
- .option('-n, --sql-mapping <style>', { valid: ['plain', 'quoted', 'hdbcds'], aliases: [ '--names' ] })
263
+ .option('-f, --odata-format <format>', { valid: [ 'flat', 'structured' ] })
264
+ .option('-n, --sql-mapping <style>', { valid: [ 'plain', 'quoted', 'hdbcds' ], aliases: [ '--names' ] })
258
265
  .option('-s, --service-names <list>')
259
266
  .option(' --transitive-localized-views')
260
267
  .help(`
@@ -312,6 +319,8 @@ optionProcessor.command('J, forJava')
312
319
 
313
320
  optionProcessor.command('C, toCdl')
314
321
  .option('-h, --help')
322
+ .option(' --render-cdl-definition-nesting')
323
+ .option(' --render-cdl-common-namespace')
315
324
  .help(`
316
325
  Usage: cdsc toCdl [options] <files...>
317
326
 
@@ -319,28 +328,34 @@ optionProcessor.command('C, toCdl')
319
328
 
320
329
  Options
321
330
  -h, --help Show this help text
331
+ --render-cdl-definition-nesting If set, definitions will be nested
332
+ inside services/contexts instead of having only top-level
333
+ definitions.
334
+ --render-cdl-common-namespace If true and render-cdl-definition-nesting
335
+ is set, a common namespace will be extracted and rendered.
322
336
  `);
323
337
 
324
338
  optionProcessor.command('Q, toSql')
325
339
  .option('-h, --help')
326
- .option('-n, --sql-mapping <style>', { valid: ['plain', 'quoted', 'hdbcds'], aliases: [ '--names' ] })
327
- .option('-d, --sql-dialect <dialect>', { valid: ['hana', 'sqlite', 'plain', 'postgres', 'h2'], aliases: [ '--dialect' ] })
340
+ .option('-n, --sql-mapping <style>', { valid: [ 'plain', 'quoted', 'hdbcds' ], aliases: [ '--names' ] })
341
+ .option('-d, --sql-dialect <dialect>', { valid: [ 'hana', 'sqlite', 'plain', 'postgres', 'h2' ], aliases: [ '--dialect' ] })
328
342
  .option(' --render-virtual')
329
343
  .option(' --joinfk')
330
344
  .option('-u, --user <user>')
331
345
  .option('-l, --locale <locale>')
332
- .option('-s, --src <style>', { valid: ['sql', 'hdi'] })
346
+ .option('-s, --src <style>', { valid: [ 'sql', 'hdi' ] })
333
347
  .option('-c, --csn')
334
348
  .option(' --integrity-not-validated')
335
349
  .option(' --integrity-not-enforced')
336
- .option(' --assert-integrity <mode>', { valid: ['true', 'false', 'individual'] })
337
- .option(' --assert-integrity-type <type>', { valid: ['RT', 'DB'], ignoreCase: true })
350
+ .option(' --assert-integrity <mode>', { valid: [ 'true', 'false', 'individual' ] })
351
+ .option(' --assert-integrity-type <type>', { valid: [ 'RT', 'DB' ], ignoreCase: true })
338
352
  .option(' --constraints-in-create-table')
339
353
  .option(' --pre2134ReferentialConstraintNames')
340
354
  .option(' --disable-hana-comments')
341
355
  .option(' --generated-by-comment')
342
356
  .option(' --better-sqlite-session-variables <bool>')
343
357
  .option(' --transitive-localized-views')
358
+ .option(' --boolean-equality')
344
359
  .option(' --with-hana-associations <bool>', { valid: [ 'true', 'false' ] })
345
360
  .option(' --standard-database-functions')
346
361
  .help(`
@@ -406,11 +421,12 @@ optionProcessor.command('Q, toSql')
406
421
  true : (default) Render "WITH ASSOCIATIONS"
407
422
  false : Do not render "WITH ASSOCIATIONS"
408
423
  --standard-database-functions Enable rendering of standard database function mappings.
424
+ --boolean-equality Enable support for boolean logic '!=' operator.
409
425
  `);
410
426
 
411
427
  optionProcessor.command('toRename')
412
428
  .option('-h, --help')
413
- .option('-n, --sql-mapping <style>', { valid: ['quoted', 'hdbcds'], aliases: ['--names'] })
429
+ .option('-n, --sql-mapping <style>', { valid: [ 'quoted', 'hdbcds' ], aliases: [ '--names' ] })
414
430
  .help(`
415
431
  Usage: cdsc toRename [options] <files...>
416
432
 
@@ -432,14 +448,14 @@ optionProcessor.command('toRename')
432
448
 
433
449
  optionProcessor.command('manageConstraints')
434
450
  .option('-h, --help')
435
- .option('-n, --sql-mapping <style>', { valid: ['plain', 'quoted', 'hdbcds'], aliases: ['--names'] })
436
- .option('-s, --src <style>', { valid: ['sql', 'hdi'] })
451
+ .option('-n, --sql-mapping <style>', { valid: [ 'plain', 'quoted', 'hdbcds' ], aliases: [ '--names' ] })
452
+ .option('-s, --src <style>', { valid: [ 'sql', 'hdi' ] })
437
453
  .option(' --drop')
438
454
  .option(' --alter')
439
455
  .option(' --violations')
440
456
  .option(' --integrity-not-validated')
441
457
  .option(' --integrity-not-enforced')
442
- .option('-d, --sql-dialect <dialect>', { valid: ['hana', 'sqlite', 'plain', 'postgres', 'h2'], aliases: [ '--dialect' ] })
458
+ .option('-d, --sql-dialect <dialect>', { valid: [ 'hana', 'sqlite', 'plain', 'postgres', 'h2' ], aliases: [ '--dialect' ] })
443
459
  .help(`
444
460
  Usage: cdsc manageConstraints [options] <files...>
445
461
 
@@ -478,10 +494,9 @@ optionProcessor.command('manageConstraints')
478
494
 
479
495
  optionProcessor.command('toCsn')
480
496
  .option('-h, --help')
481
- .option('-f, --csn-flavor <flavor>', { valid: ['client', 'gensrc', 'universal'], aliases: ['--flavor'] })
497
+ .option('-f, --csn-flavor <flavor>', { valid: [ 'client', 'gensrc', 'universal' ], aliases: [ '--flavor' ] })
482
498
  .option(' --with-localized')
483
499
  .option(' --with-locations')
484
- .option(' --struct-xpr')
485
500
  .option(' --transitive-localized-views')
486
501
  .help(`
487
502
  Usage: cdsc toCsn [options] <files...>
@@ -505,7 +520,6 @@ optionProcessor.command('toCsn')
505
520
 
506
521
  Internal options (for testing only, may be changed/removed at any time)
507
522
  --with-localized Add localized convenience views to the CSN output.
508
- --struct-xpr Write structured expressions to the CSN output.
509
523
  `);
510
524
 
511
525
  optionProcessor.command('parseCdl')
@@ -576,10 +590,10 @@ optionProcessor.command('inspect')
576
590
 
577
591
  optionProcessor.command('forEffective')
578
592
  .option('-h, --help')
579
- .option('--resolve-simple-types <val>', { valid: ['true', 'false'] } )
580
- .option('--resolve-projections <val>', { valid: ['true', 'false'] } )
581
- .option('--remap-odata-annotations <val>', { valid: ['true', 'false'] } )
582
- .option('--keep-localized <val>', { valid: ['true', 'false'] } )
593
+ .option('--resolve-simple-types <val>', { valid: [ 'true', 'false' ] } )
594
+ .option('--resolve-projections <val>', { valid: [ 'true', 'false' ] } )
595
+ .option('--remap-odata-annotations <val>', { valid: [ 'true', 'false' ] } )
596
+ .option('--keep-localized <val>', { valid: [ 'true', 'false' ] } )
583
597
  .option('--effective-service-name <name>')
584
598
  .positionalArgument('<files...>')
585
599
  .help(`
@@ -608,8 +622,8 @@ optionProcessor.command('forEffective')
608
622
 
609
623
  optionProcessor.command('forSeal')
610
624
  .option('-h, --help')
611
- .option('--remap-odata-annotations <val>', { valid: ['true', 'false'] } )
612
- .option('--derive-analytical-annotations <val>', { valid: ['true', 'false'] })
625
+ .option('--remap-odata-annotations <val>', { valid: [ 'true', 'false' ] } )
626
+ .option('--derive-analytical-annotations <val>', { valid: [ 'true', 'false' ] })
613
627
  .positionalArgument('<files...>')
614
628
  .help(`
615
629
  Usage: cdsc forSeal [options] <files...>
@@ -627,5 +641,5 @@ optionProcessor.command('forSeal')
627
641
  `);
628
642
 
629
643
  module.exports = {
630
- optionProcessor
644
+ optionProcessor,
631
645
  };