@sap/cds-compiler 3.5.4 → 3.6.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 (83) hide show
  1. package/CHANGELOG.md +56 -2
  2. package/bin/cdsc.js +14 -6
  3. package/doc/CHANGELOG_ARCHIVE.md +10 -10
  4. package/doc/CHANGELOG_DEPRECATED.md +2 -2
  5. package/lib/api/main.js +32 -55
  6. package/lib/api/validate.js +5 -0
  7. package/lib/base/message-registry.js +104 -32
  8. package/lib/base/messages.js +277 -212
  9. package/lib/base/optionProcessorHelper.js +9 -2
  10. package/lib/base/shuffle.js +50 -0
  11. package/lib/checks/actionsFunctions.js +37 -20
  12. package/lib/checks/foreignKeys.js +13 -6
  13. package/lib/checks/nonexpandableStructured.js +1 -2
  14. package/lib/checks/onConditions.js +21 -19
  15. package/lib/checks/parameters.js +1 -1
  16. package/lib/checks/queryNoDbArtifacts.js +2 -0
  17. package/lib/checks/types.js +16 -22
  18. package/lib/compiler/assert-consistency.js +31 -28
  19. package/lib/compiler/builtins.js +20 -4
  20. package/lib/compiler/checks.js +72 -63
  21. package/lib/compiler/define.js +396 -314
  22. package/lib/compiler/extend.js +55 -49
  23. package/lib/compiler/index.js +5 -0
  24. package/lib/compiler/populate.js +28 -11
  25. package/lib/compiler/propagator.js +2 -1
  26. package/lib/compiler/resolve.js +28 -13
  27. package/lib/compiler/shared.js +15 -10
  28. package/lib/compiler/utils.js +7 -7
  29. package/lib/edm/annotations/genericTranslation.js +51 -46
  30. package/lib/edm/annotations/preprocessAnnotations.js +37 -40
  31. package/lib/edm/csn2edm.js +69 -21
  32. package/lib/edm/edm.js +2 -2
  33. package/lib/edm/edmInboundChecks.js +6 -8
  34. package/lib/edm/edmPreprocessor.js +88 -80
  35. package/lib/edm/edmUtils.js +6 -15
  36. package/lib/gen/Dictionary.json +81 -13
  37. package/lib/gen/language.checksum +1 -1
  38. package/lib/gen/language.interp +2 -1
  39. package/lib/gen/languageParser.js +4680 -4484
  40. package/lib/inspect/inspectModelStatistics.js +2 -1
  41. package/lib/inspect/inspectPropagation.js +2 -1
  42. package/lib/json/from-csn.js +131 -78
  43. package/lib/json/to-csn.js +39 -23
  44. package/lib/language/antlrParser.js +0 -3
  45. package/lib/language/docCommentParser.js +7 -3
  46. package/lib/language/errorStrategy.js +3 -2
  47. package/lib/language/genericAntlrParser.js +96 -41
  48. package/lib/language/language.g4 +112 -128
  49. package/lib/language/multiLineStringParser.js +2 -1
  50. package/lib/main.d.ts +115 -2
  51. package/lib/main.js +16 -3
  52. package/lib/model/csnRefs.js +3 -3
  53. package/lib/model/csnUtils.js +109 -179
  54. package/lib/model/enrichCsn.js +13 -8
  55. package/lib/model/revealInternalProperties.js +4 -3
  56. package/lib/optionProcessor.js +19 -3
  57. package/lib/render/manageConstraints.js +11 -15
  58. package/lib/render/toCdl.js +144 -47
  59. package/lib/render/toHdbcds.js +22 -22
  60. package/lib/render/toRename.js +3 -4
  61. package/lib/render/toSql.js +29 -20
  62. package/lib/render/utils/delta.js +3 -1
  63. package/lib/render/utils/sql.js +2 -14
  64. package/lib/transform/db/associations.js +6 -6
  65. package/lib/transform/db/cdsPersistence.js +3 -3
  66. package/lib/transform/db/constraints.js +4 -6
  67. package/lib/transform/db/expansion.js +4 -4
  68. package/lib/transform/db/flattening.js +12 -15
  69. package/lib/transform/db/temporal.js +4 -3
  70. package/lib/transform/db/transformExists.js +2 -1
  71. package/lib/transform/draft/db.js +7 -7
  72. package/lib/transform/forOdataNew.js +15 -4
  73. package/lib/transform/forRelationalDB.js +53 -39
  74. package/lib/transform/odata/toFinalBaseType.js +106 -82
  75. package/lib/transform/odata/typesExposure.js +26 -17
  76. package/lib/transform/odata/utils.js +1 -1
  77. package/lib/transform/parseExpr.js +1 -1
  78. package/lib/transform/transformUtilsNew.js +33 -10
  79. package/lib/transform/translateAssocsToJoins.js +8 -7
  80. package/lib/transform/universalCsn/coreComputed.js +7 -5
  81. package/lib/transform/universalCsn/universalCsnEnricher.js +12 -4
  82. package/lib/utils/timetrace.js +2 -2
  83. package/package.json +1 -2
package/CHANGELOG.md CHANGED
@@ -7,19 +7,71 @@
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 3.6.0 - 2023-01-25
11
+
12
+ ### Added
13
+
14
+ - API: There are new API functions for `to.cdl`: `smartId`, `smartFunctionId` and `delimitedId`.
15
+ - CDL parser: when defining a parameter for entities, actions or functions,
16
+ you can use a regular identifier for its name even if that is a reserved name like `in`.
17
+ - The first parameter of a bound action or function can be typed with `$self` or `many $self`
18
+ even if no type named `$self` exists.
19
+ - If an aspect `sap.common.TextsAspect` exists in the `sap.common` context, it will be included
20
+ in all `.texts` entities. This allows to extend `.texts` entities via extending the aspect.
21
+ Example:
22
+ ```cds
23
+ entity E {
24
+ key id : Integer;
25
+ content: localized String;
26
+ }
27
+ extend sap.common.TextsAspect with {
28
+ elem: String;
29
+ };
30
+ // from @sap/cds common.cds
31
+ aspect sap.common.TextsAspect {
32
+ key locale: String;
33
+ }
34
+ ```
35
+ - to.edm(x): Support explicit binding parameter `<id>: [many] $self` for OData V4 only.
36
+ The explicit binding parameter is rendered as any other parameter and `$self` is replaced with
37
+ the binding type but only if no `$self` definition exists in the model. This gives full control
38
+ over the binding parameter including name, nullability, default value and annotations.
39
+ The explicit binding parameter is ignored for OData V2 and has precedence over `@cds.odata.bindingparameter`.
40
+
41
+ ### Changed
42
+
43
+ - Many messages concerning the CDL and CSN syntax are improved:
44
+ affects message ids (`syntax-…`), message texts and the error locations.
45
+ - Duplicate doc-comments are now errors, similar to duplicate annotations.
46
+ - Update OData vocabularies 'Aggregation', 'Analytics', 'Capabilities','Common', 'ODM', 'Offline',
47
+ 'PDF', 'Session', 'UI'.
48
+
49
+ ### Fixed
50
+
51
+ - If an entity with parameters is auto-exposed, the generated projection now has
52
+ the same formal parameters and its query forwards these parameters to the origin entity.
53
+ - to.hdbcds: Aliases for foreign `keys` were not quoted if necessary.
54
+ - to.cdl:
55
+ + Aliases for `expand` and foreign `keys` were not quoted if necessary.
56
+ + Query functions that are CDL keywords were not properly quoted.
57
+ + CSN `doc` properties containing `*/` resulted in invalid CDL.
58
+ To avoid compilation issues, `*/` is escaped as `*\/`.
59
+ - to.edm(x): Respect record type hint `$Type` in EDM JSON as full qualified `@type` URI property.
60
+
10
61
  ## Version 3.5.4 - 2023-01-10
11
62
 
12
63
  ### Fixed
13
64
 
14
65
  - Allow window functions also with a deprecated flag being set.
15
66
  - to.edm(x): Fix program abort due to malformed error location in EDM annotation preprocessing.
16
- - to.sql/hdi/hdbcds: The option `pre2134ReferentialConstraintNames` can be used to omit the referential constraint identifier prefix "c__".
67
+ - to.sql/hdi/hdbcds: The option `pre2134ReferentialConstraintNames` can be used to omit the referential
68
+ constraint identifier prefix `c__`.
17
69
 
18
70
  ## Version 3.5.2 - 2022-12-20
19
71
 
20
72
  ### Fixed
21
73
 
22
- - to.sql/hdi/hdbcds: Don't process references in actions, as they have no impact on the database - avoids internal errors
74
+ - to.sql/hdi/hdbcds: Don't process references in actions, as they have no impact on the database - avoids internal errors.
23
75
 
24
76
  ## Version 3.5.0 - 2022-12-07
25
77
 
@@ -51,6 +103,8 @@ The compiler behavior concerning `beta` features can change at any time without
51
103
  as the renderer does not modify it.
52
104
  - A new warning is emitted if compositions of anonymous aspects are used with the `Association`
53
105
  keyword instead of `Composition`. Replace the former with the latter to fix the warning.
106
+ - The previous info messages about annotating undefined artifacts (e.g. `anno-undefined-art`)
107
+ are now warnings.
54
108
 
55
109
  ### Removed
56
110
 
package/bin/cdsc.js CHANGED
@@ -128,8 +128,7 @@ function cdsc_main() {
128
128
  return;
129
129
  }
130
130
 
131
- // Default warning level is 2 (info)
132
- // FIXME: Is that not set anywhere in the API?
131
+ // Default warning level is 2 (info); default value only needed for cdsc output
133
132
  if (!cmdLine.options.warning)
134
133
  cmdLine.options.warning = 2;
135
134
 
@@ -184,6 +183,15 @@ function cdsc_main() {
184
183
  if (cmdLine.options.betaMode)
185
184
  cmdLine.options.beta = availableBetaFlags;
186
185
 
186
+ const { shuffle } = cmdLine.options;
187
+ if (shuffle != null) {
188
+ const num = Number.parseInt( shuffle, 10 );
189
+ cmdLine.options.testMode = (num > 0)
190
+ ? num
191
+ : Math.floor( Math.random() * 4294967296 ) + 1;
192
+ console.error( `Running ‘${cmdLine.command}’ with test-mode shuffle ${cmdLine.options.testMode} …` );
193
+ }
194
+
187
195
  // If set through CLI (and not options file), `deprecated` is a string and needs processing.
188
196
  if (cmdLine.options.deprecated && typeof cmdLine.options.deprecated === 'string') {
189
197
  const features = cmdLine.options.deprecated.split(',');
@@ -382,7 +390,7 @@ function executeCommandLine( command, options, args ) {
382
390
  function manageConstraints( model ) {
383
391
  const csn = options.directBackend ? model : compactModel(model, options);
384
392
  const alterConstraintsResult = alterConstraintsWithCsn(csn, options);
385
- const { src } = options.manageConstraints || {};
393
+ const { src } = options || {};
386
394
  Object.keys(alterConstraintsResult).forEach((id) => {
387
395
  const renderedConstraintStatement = alterConstraintsResult[id];
388
396
  if (src === 'hdi')
@@ -492,7 +500,7 @@ function executeCommandLine( command, options, args ) {
492
500
  }
493
501
  else if (options.noMessageContext) {
494
502
  messages.filter(msg => (messageLevels[msg.severity] <= options.warning))
495
- .forEach(msg => log(main.messageString(msg, normalizeFilename, !options.showMessageId)));
503
+ .forEach(msg => log(main.messageString(msg, normalizeFilename, !!options.noMessageId)));
496
504
  }
497
505
  else {
498
506
  // Contains file-contents that are split at '\n'. Try to avoid multiple `.split()` calls.
@@ -509,7 +517,7 @@ function executeCommandLine( command, options, args ) {
509
517
  const fullFilePath = name ? path.resolve('', name) : undefined;
510
518
  log(main.messageStringMultiline(msg, {
511
519
  normalizeFilename,
512
- noMessageId: !options.showMessageId,
520
+ noMessageId: !!options.noMessageId,
513
521
  withLineSpacer: true,
514
522
  hintExplanation: true,
515
523
  color: options.color,
@@ -521,7 +529,7 @@ function executeCommandLine( command, options, args ) {
521
529
  }
522
530
  log(); // newline
523
531
  });
524
- if (options.showMessageId && hasAtLeastOneExplanation)
532
+ if (!options.noMessageId && hasAtLeastOneExplanation)
525
533
  log(`${colorTerm.asHelp('help')}: Messages marked with '…' have an explanation text. Use \`cdsc explain <message-id>\` for a more detailed error description.`);
526
534
  }
527
535
  return model;
@@ -584,7 +584,7 @@ synchronously.
584
584
  for a local definition of `Foo` probably having a different full name.
585
585
  + Localized convenience views are no longer generated by the core compiler but added by the `for.odata`
586
586
  and `to.sql/hdi/hdbcds` processing on demand.
587
- + Minimize name clashes when calculating names for autoexposed entities,
587
+ + Minimize name clashes when calculating names for auto-exposed entities,
588
588
  extends the v1 option `dependentAutoexposed` to sub artifacts of entites (see “Added”).
589
589
  + Ambiguities when redirecting associations now always lead to compile errors;
590
590
  you might want to use the new annotation `@cds.redirection.target` to solve them.
@@ -760,7 +760,7 @@ synchronously.
760
760
 
761
761
  ### Fixed
762
762
 
763
- - Correct calculation of dependent autoexposed entity name
763
+ - Correct calculation of dependent auto-exposed entity name
764
764
  (fixing a potential regression with v1.50.0)
765
765
  - to.hdi.migration: Correctly handle "temporal" and other cases when rendering expressions
766
766
  - to.edm(x):
@@ -1177,7 +1177,7 @@ synchronously.
1177
1177
  - Properly consider targets of compositions in `mixin`s to be autoexposed.
1178
1178
  - Uniformly limit propagation of `@cds.autoexposed`, i.e.
1179
1179
  there is not inheritance from a query source navigating along an association.
1180
- Previously, compiling a compiled model could lead to new autoexposed entities.
1180
+ Previously, compiling a compiled model could lead to new auto-exposed entities.
1181
1181
  - OData:
1182
1182
  + V2: Distribute various `@sap` specific annotations to the entity container.
1183
1183
  + Always set attribute `Nullable` on properties of type `Collection()`.
@@ -1196,7 +1196,7 @@ synchronously.
1196
1196
  - Allow to declare `many/array of` elements, parameters and return types to be `(not) null`.
1197
1197
  The nullability applies to the array items of the element, not the element itself.
1198
1198
  - New boolean option `dependentAutoexposed` to avoid name clashes in dependent
1199
- autoexposed entities (text entities, components of managed compositions).
1199
+ auto-exposed entities (text entities, components of managed compositions).
1200
1200
  - cdsc: Add toOdata version 'v4x' to combine `{ version: 'v4', odataFormat: 'structured', odataContainment: true }`.
1201
1201
 
1202
1202
  ### Changed
@@ -1971,7 +1971,7 @@ Changes
1971
1971
 
1972
1972
  Fixes
1973
1973
 
1974
- * Make `annotate` statements on members of autoexposed entities and
1974
+ * Make `annotate` statements on members of auto-exposed entities and
1975
1975
  automatically created text entities work.
1976
1976
 
1977
1977
  ## Version 1.17.2
@@ -2098,7 +2098,7 @@ Fixes
2098
2098
  * Consider associations in `from` clause for `on` condition rewrite.
2099
2099
  * Make the CSN parser always produce the correct result for `null`.
2100
2100
  * Propagate `@cds.autoexpose` along primary query source in all circumstances.
2101
- * Make `annotate` statements on autoexposed entities work in circumstances.
2101
+ * Make `annotate` statements on auto-exposed entities work in circumstances.
2102
2102
  * Do not dump when magic variables like `$now` or `current_date` had been used
2103
2103
  in an entitiy for which the compiler creates a localized convenience view.
2104
2104
  * Fix order problem in creation of association `DraftAdministrativeData` for draft enabled entities.
@@ -2223,7 +2223,7 @@ Changes
2223
2223
  + Auto-exposure via `Composition of` now works in all circumstances.
2224
2224
  + Other features like "localized" work for auto-exposed entity and/or with implicitly redirected association.
2225
2225
  + __Redirections for associations which are sub elements do not work__.
2226
- * The name of an autoexposed entity now looks like `<Service>.<LastNamePart>`
2226
+ * The name of an auto-exposed entity now looks like `<Service>.<LastNamePart>`
2227
2227
  where `<LastNamePart>` is the part of the name of the original entity after the final dot.
2228
2228
  If you get an error because of name clashes, just expose one entity explicitly
2229
2229
  (or use the option `longAutoexposed`).
@@ -2307,7 +2307,7 @@ Changes
2307
2307
  * Produce all CSN output in version 1.0 by default.
2308
2308
  * Virtual elements cannot be used in expressions.
2309
2309
  * Command `toRename` creates a stored procedure instead of individual statements.
2310
- * Don't autoexpose composition target which is annotated with `@cds.autoexpose: false`.
2310
+ * Don't auto-expose composition target which is annotated with `@cds.autoexpose: false`.
2311
2311
 
2312
2312
  Fixes
2313
2313
  * OData:
@@ -2323,8 +2323,8 @@ Fixes
2323
2323
  ## Version 1.10.0
2324
2324
 
2325
2325
  Features
2326
- * Annotate entities with `@cds.autoexposed` that are autoexposed in a service.
2327
- * Always autoexpose composition targets without annotating them with `@cds.autoexpose`.
2326
+ * Annotate entities with `@cds.autoexposed` that are auto-exposed in a service.
2327
+ * Always auto-expose composition targets without annotating them with `@cds.autoexpose`.
2328
2328
  * For associations in a service with targets which are not in a service:
2329
2329
  + automatically exclude them if the associaiton is inferred (via select * or include),
2330
2330
  + signal an error if the association is explicitly defined in the service.
@@ -115,12 +115,12 @@ behavior (without v1 options `dependentAutoexposed` and `longAutoexposed`).
115
115
  ### Added `longAutoexposed`
116
116
 
117
117
  When this option is set (and `generatedEntityNameWithUnderscore`),
118
- the names of autoexposed entities are calculated according to the
118
+ the names of auto-exposed entities are calculated according to the
119
119
  compiler v1 option `longAutoexposed`.
120
120
 
121
121
  ### Added `generatedEntityNameWithUnderscore`
122
122
 
123
- Keep using `_` is separator for generated autoexposed entities and for entities
123
+ Keep using `_` is separator for generated auto-exposed entities and for entities
124
124
  created for managed compositions. It also disables a definition `A.B.C` if `A`
125
125
  or `A.B` is a definition other than a context or service (v1 behavior).
126
126
 
package/lib/api/main.js CHANGED
@@ -130,6 +130,7 @@ function isPreTransformed( csn, transformation ) {
130
130
  * @returns {object} Return an oData-pre-processed CSN
131
131
  */
132
132
  function odataInternal( csn, internalOptions ) {
133
+ internalOptions.transformation = 'odata';
133
134
  const oDataCsn = forOdataNew.transform4odataWithCsn(csn, internalOptions);
134
135
  attachTransformerCharacteristics(oDataCsn, 'odata', internalOptions, relevantOdataOptions, warnAboutMismatchOdata);
135
136
  return oDataCsn;
@@ -143,6 +144,7 @@ function odataInternal( csn, internalOptions ) {
143
144
  * @returns {oDataCSN} Return an oData-pre-processed CSN
144
145
  */
145
146
  function odata( csn, options = {} ) {
147
+ traceApi("Options passed into 'for.odata'", options);
146
148
  const internalOptions = prepareOptions.for.odata(options);
147
149
  return odataInternal(csn, internalOptions);
148
150
  }
@@ -151,11 +153,12 @@ function odata( csn, options = {} ) {
151
153
  * Process the given csn back to cdl.
152
154
  *
153
155
  * @param {object} csn CSN to process
154
- * @param {object} [externalOptions={}] Options
156
+ * @param {object} [options={}] Options
155
157
  * @returns {object} { model: string, namespace: string }
156
158
  */
157
- function cdl( csn, externalOptions = {} ) {
158
- const internalOptions = prepareOptions.to.cdl(externalOptions);
159
+ function cdl( csn, options = {} ) {
160
+ traceApi("Options passed into 'to.cdl'", options);
161
+ const internalOptions = prepareOptions.to.cdl(options);
159
162
  return toCdl.csnToCdl(csn, internalOptions);
160
163
  }
161
164
 
@@ -214,6 +217,7 @@ function forHdbcds( csn, options = {} ) {
214
217
  * @returns {SQL[]} Array of SQL statements, tables first, views second
215
218
  */
216
219
  function sql( csn, options = {} ) {
220
+ traceApi("Options passed into 'to.sql'", options);
217
221
  const internalOptions = prepareOptions.to.sql(options);
218
222
  internalOptions.transformation = 'sql';
219
223
 
@@ -226,50 +230,6 @@ function sql( csn, options = {} ) {
226
230
  return result.map(obj => obj.sql).filter(create => create);
227
231
  }
228
232
 
229
- /**
230
- * Render the given deltaCSN as SQL.
231
- *
232
- * @param {CSN.Model} csn A clean input CSN
233
- * @param {CSN.Model} deltaCsn A CSN representing new entities and extensions
234
- * @param {SqlOptions} [options={}] Options
235
- * @returns {object} - definitions: An array of objects with all artifacts in the after-image. Each object specifies
236
- * the artifact filename, the suffix, and the corresponding SQL statement to create
237
- * the artifact.
238
- * - deletions: An array of objects with the deleted artifacts. Each object specifies the artifact
239
- * filename and the suffix.
240
- * - migrations: An array of objects with the changed (migrated) artifacts. Each object specifies the
241
- * artifact filename, the suffix, and the changeset (an array of changes, each specifying
242
- * whether it incurs potential data loss, and its respective SQL statement(s), with
243
- * multiple statements concatenated as a multi-line string in case the change e.g.
244
- * consists of a column drop and add).
245
- */
246
- function mtx( csn, deltaCsn, options = {} ) {
247
- if (!baseModel.isBetaEnabled(options, 'to.mtx'))
248
- throw new Error('to.mtx is only available with beta flag `to.mtx`');
249
-
250
- const internalOptions = prepareOptions.to.sql(options);
251
- // TODO: Use compiler.compileSources() when this function is moved to lib/main.js
252
- const merged = toCsn.compactModel(compiler.compileSourcesX({ 'base.csn': csn, 'delta.csn': deltaCsn }), options);
253
- const baseSql = forSql(csn, options);
254
- const mergedSql = forSql(merged, options);
255
- const diff = modelCompare.compareModels(baseSql, mergedSql, options);
256
- // Delete artifacts that are already present in csn
257
- Object.keys(baseSql.definitions).forEach((artifactName) => {
258
- if (diff.definitions[artifactName]) // don't render again, but need info for primary key extension
259
- diff.definitions[artifactName]['@cds.persistence.skip'] = true;
260
- });
261
-
262
- internalOptions.forHana = true;
263
- internalOptions.beta.sqlExtensions = true;
264
- const { deletions, migrations, ...additions } = toSql.toSqlDdl(diff, internalOptions);
265
-
266
- return {
267
- additions: createSqlDefinitions(additions, mergedSql),
268
- deletions: createSqlDeletions(deletions, baseSql),
269
- migrations: createSqlMigrations(migrations, mergedSql),
270
- };
271
- }
272
-
273
233
  /**
274
234
  * Process the given CSN into HDI artifacts.
275
235
  *
@@ -278,6 +238,7 @@ function mtx( csn, deltaCsn, options = {} ) {
278
238
  * @returns {HDIArtifacts} { <filename>:<content>, ...}
279
239
  */
280
240
  function hdi( csn, options = {} ) {
241
+ traceApi("Options passed into 'to.hdi'", options);
281
242
  const internalOptions = prepareOptions.to.hdi(options);
282
243
 
283
244
  // we need the CSN for view sorting
@@ -380,14 +341,15 @@ function remapName( key, csn, filter = () => true ) {
380
341
  * - createsAndAlters: An array of SQL statements to ALTER/CREATE tables/views
381
342
  */
382
343
  function sqlMigration( csn, options, beforeImage ) {
344
+ traceApi("Options passed into 'to.sql.migration'", options);
383
345
  const internalOptions = prepareOptions.to.sql(options);
384
- const { error, throwWithError } = messages.makeMessageFunction(csn, options, 'to.sql.migration');
346
+ const { error, throwWithError } = messages.makeMessageFunction(csn, internalOptions, 'to.sql.migration');
385
347
 
386
348
  // Prepare after-image.
387
- const afterImage = forSql(csn, options);
349
+ const afterImage = forSql(csn, internalOptions);
388
350
  // Compare both images.
389
351
  const diff = modelCompare.compareModels(beforeImage || afterImage, afterImage, internalOptions);
390
- const diffFilterObj = diffFilter[options.sqlDialect];
352
+ const diffFilterObj = diffFilter[internalOptions.sqlDialect];
391
353
 
392
354
  if (diffFilterObj) {
393
355
  diff.extensions.forEach(ex => diffFilterObj.extension(ex, error));
@@ -489,6 +451,7 @@ function sqlMigration( csn, options, beforeImage ) {
489
451
  * @returns {migration} The migration result
490
452
  */
491
453
  function hdiMigration( csn, options, beforeImage ) {
454
+ traceApi("Options passed into 'to.hdi.migration'", options);
492
455
  const internalOptions = prepareOptions.to.hdi(options);
493
456
 
494
457
  // Prepare after-image.
@@ -569,6 +532,7 @@ sql.migration = sqlMigration;
569
532
  * @returns {HDBCDS} { <filename>:<content>, ...}
570
533
  */
571
534
  function hdbcds( csn, options = {} ) {
535
+ traceApi("Options passed into 'to.hdbcds'", options);
572
536
  const internalOptions = prepareOptions.to.hdbcds(options);
573
537
  internalOptions.transformation = 'hdbcds';
574
538
 
@@ -585,6 +549,7 @@ function hdbcds( csn, options = {} ) {
585
549
  * @returns {edm} The JSON representation of the service
586
550
  */
587
551
  function edm( csn, options = {} ) {
552
+ traceApi("Options passed into 'to.edm'", options);
588
553
  // If not provided at all, set service to undefined to trigger validation
589
554
  const internalOptions = prepareOptions.to.edm(
590
555
  // eslint-disable-next-line comma-dangle
@@ -615,6 +580,7 @@ edm.all = edmall;
615
580
  * @returns {edms} { <service>:<JSON representation>, ...}
616
581
  */
617
582
  function edmall( csn, options = {} ) {
583
+ traceApi("Options passed into 'to.edm.all'", options);
618
584
  const internalOptions = prepareOptions.to.edm(options);
619
585
  const { error } = messages.makeMessageFunction(csn, internalOptions, 'for.odata');
620
586
 
@@ -645,6 +611,7 @@ function edmall( csn, options = {} ) {
645
611
  * @returns {edmx} The XML representation of the service
646
612
  */
647
613
  function edmx( csn, options = {} ) {
614
+ traceApi("Options passed into 'to.edmx'", options);
648
615
  // If not provided at all, set service to undefined to trigger validation
649
616
  const internalOptions = prepareOptions.to.edmx(
650
617
  // eslint-disable-next-line comma-dangle
@@ -676,6 +643,7 @@ edmx.all = edmxall;
676
643
  * @returns {edmxs} { <service>:<XML representation>, ...}
677
644
  */
678
645
  function edmxall( csn, options = {} ) {
646
+ traceApi("Options passed into 'to.edmx.all'", options);
679
647
  const internalOptions = prepareOptions.to.edmx(options);
680
648
 
681
649
  const result = {};
@@ -792,6 +760,20 @@ function flattenResultStructure( toProcess ) {
792
760
  return result;
793
761
  }
794
762
 
763
+ /**
764
+ * Print args to stderr if CDSC_TRACE_API is set
765
+ *
766
+ * @param {...any} args
767
+ */
768
+ function traceApi( ...args ) {
769
+ if (process?.env?.CDSC_TRACE_API !== undefined) {
770
+ for (const arg of args) {
771
+ // eslint-disable-next-line no-console
772
+ console.error( `${ typeof arg === 'object' ? JSON.stringify(arg, null, 2) : arg }`);
773
+ }
774
+ }
775
+ }
776
+
795
777
  module.exports = {
796
778
  odata: publishCsnProcessor(odata, 'for.odata'),
797
779
  cdl: publishCsnProcessor(cdl, 'to.cdl'),
@@ -804,8 +786,6 @@ module.exports = {
804
786
  for_sql: publishCsnProcessor(forSql, 'for.sql'),
805
787
  for_hdi: publishCsnProcessor(forHdi, 'for.hdi'),
806
788
  for_hdbcds: publishCsnProcessor(forHdbcds, 'for.hdbcds'),
807
- /** beta - WIP */
808
- mtx: publishCsnProcessor(mtx, 'to.mtx'),
809
789
  /** Deprecated, will be removed in cds-compiler@v4 */
810
790
  preparedCsnToEdmx,
811
791
  preparedCsnToEdm,
@@ -826,9 +806,6 @@ function publishCsnProcessor( processor, _name ) {
826
806
  if (processor.migration)
827
807
  api.migration = publishCsnProcessor(processor.migration, `${ _name }.migration`);
828
808
 
829
- if (processor.mtx)
830
- api.mtx = publishCsnProcessor(processor.mtx, `${ _name }.mtx`);
831
-
832
809
  return api;
833
810
 
834
811
  /**
@@ -109,6 +109,11 @@ const validators = {
109
109
  expected: () => 'type string',
110
110
  found: val => `type ${ typeof val }`,
111
111
  },
112
+ testMode: {
113
+ validate: val => typeof val === 'boolean' || typeof val === 'number',
114
+ expected: () => 'type boolean|number',
115
+ found: val => `type ${ typeof val }`,
116
+ },
112
117
  dictionaryPrototype: {
113
118
  validate: () => true,
114
119
  },