@sap/cds-compiler 2.15.4 → 3.0.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 (105) hide show
  1. package/CHANGELOG.md +33 -1590
  2. package/bin/cdsc.js +36 -33
  3. package/doc/CHANGELOG_ARCHIVE.md +1592 -0
  4. package/doc/CHANGELOG_BETA.md +3 -4
  5. package/doc/CHANGELOG_DEPRECATED.md +35 -1
  6. package/doc/{DeprecatedOptions.md → DeprecatedOptions_v2.md} +3 -1
  7. package/doc/Versioning.md +20 -1
  8. package/lib/api/.eslintrc.json +2 -2
  9. package/lib/api/main.js +220 -103
  10. package/lib/api/options.js +15 -85
  11. package/lib/api/validate.js +6 -10
  12. package/lib/base/keywords.js +216 -109
  13. package/lib/base/message-registry.js +60 -20
  14. package/lib/base/messages.js +65 -24
  15. package/lib/base/model.js +44 -2
  16. package/lib/checks/actionsFunctions.js +7 -5
  17. package/lib/checks/annotationsOData.js +1 -1
  18. package/lib/checks/cdsPersistence.js +1 -0
  19. package/lib/checks/elements.js +6 -6
  20. package/lib/checks/invalidTarget.js +1 -1
  21. package/lib/checks/nonexpandableStructured.js +1 -1
  22. package/lib/checks/queryNoDbArtifacts.js +2 -1
  23. package/lib/checks/selectItems.js +5 -1
  24. package/lib/checks/types.js +4 -2
  25. package/lib/checks/utils.js +2 -2
  26. package/lib/checks/validator.js +2 -1
  27. package/lib/compiler/assert-consistency.js +15 -10
  28. package/lib/compiler/builtins.js +87 -9
  29. package/lib/compiler/define.js +2 -2
  30. package/lib/compiler/extend.js +59 -11
  31. package/lib/compiler/finalize-parse-cdl.js +20 -9
  32. package/lib/compiler/index.js +25 -11
  33. package/lib/compiler/moduleLayers.js +7 -0
  34. package/lib/compiler/populate.js +13 -13
  35. package/lib/compiler/propagator.js +3 -3
  36. package/lib/compiler/resolve.js +193 -218
  37. package/lib/compiler/shared.js +47 -76
  38. package/lib/compiler/tweak-assocs.js +9 -10
  39. package/lib/compiler/utils.js +5 -0
  40. package/lib/edm/csn2edm.js +18 -21
  41. package/lib/edm/edmPreprocessor.js +25 -30
  42. package/lib/edm/edmUtils.js +10 -24
  43. package/lib/gen/language.checksum +1 -1
  44. package/lib/gen/language.interp +8 -30
  45. package/lib/gen/language.tokens +105 -114
  46. package/lib/gen/languageLexer.interp +1 -34
  47. package/lib/gen/languageLexer.js +889 -1007
  48. package/lib/gen/languageLexer.tokens +95 -106
  49. package/lib/gen/languageParser.js +20632 -22313
  50. package/lib/json/from-csn.js +56 -49
  51. package/lib/json/to-csn.js +10 -8
  52. package/lib/language/antlrParser.js +2 -2
  53. package/lib/language/docCommentParser.js +61 -38
  54. package/lib/language/errorStrategy.js +52 -40
  55. package/lib/language/genericAntlrParser.js +303 -229
  56. package/lib/language/language.g4 +573 -629
  57. package/lib/language/multiLineStringParser.js +14 -42
  58. package/lib/language/textUtils.js +44 -0
  59. package/lib/main.d.ts +27 -42
  60. package/lib/main.js +104 -81
  61. package/lib/model/csnRefs.js +1 -1
  62. package/lib/model/csnUtils.js +170 -283
  63. package/lib/model/revealInternalProperties.js +28 -8
  64. package/lib/model/sortViews.js +32 -31
  65. package/lib/optionProcessor.js +12 -21
  66. package/lib/render/.eslintrc.json +1 -1
  67. package/lib/render/DuplicateChecker.js +4 -7
  68. package/lib/render/manageConstraints.js +70 -2
  69. package/lib/render/toCdl.js +334 -339
  70. package/lib/render/toHdbcds.js +19 -15
  71. package/lib/render/toRename.js +44 -22
  72. package/lib/render/toSql.js +53 -51
  73. package/lib/render/utils/common.js +15 -1
  74. package/lib/render/utils/sql.js +20 -19
  75. package/lib/sql-identifier.js +6 -0
  76. package/lib/transform/db/.eslintrc.json +3 -2
  77. package/lib/transform/db/cdsPersistence.js +5 -15
  78. package/lib/transform/db/constraints.js +1 -1
  79. package/lib/transform/db/expansion.js +7 -6
  80. package/lib/transform/db/flattening.js +18 -19
  81. package/lib/transform/db/views.js +3 -3
  82. package/lib/transform/draft/.eslintrc.json +2 -2
  83. package/lib/transform/draft/db.js +6 -6
  84. package/lib/transform/draft/odata.js +6 -7
  85. package/lib/transform/forHanaNew.js +19 -22
  86. package/lib/transform/forOdataNew.js +10 -12
  87. package/lib/transform/localized.js +22 -16
  88. package/lib/transform/odata/toFinalBaseType.js +10 -10
  89. package/lib/transform/odata/typesExposure.js +3 -3
  90. package/lib/transform/odata/utils.js +1 -38
  91. package/lib/transform/transformUtilsNew.js +63 -77
  92. package/lib/transform/translateAssocsToJoins.js +2 -2
  93. package/lib/transform/universalCsn/.eslintrc.json +2 -2
  94. package/lib/transform/universalCsn/coreComputed.js +11 -6
  95. package/lib/transform/universalCsn/universalCsnEnricher.js +33 -5
  96. package/lib/utils/file.js +3 -3
  97. package/lib/utils/timetrace.js +20 -21
  98. package/package.json +35 -4
  99. package/doc/ApiMigration.md +0 -237
  100. package/doc/CommandLineMigration.md +0 -58
  101. package/doc/ErrorMessages.md +0 -175
  102. package/doc/FioriAnnotations.md +0 -94
  103. package/doc/ODataTransformation.md +0 -273
  104. package/lib/backends.js +0 -529
  105. package/lib/fix_antlr4-8_warning.js +0 -56
@@ -39,7 +39,7 @@ function tweakAssocs( model ) {
39
39
  const { environment } = model.$volatileFunctions;
40
40
 
41
41
  // behavior depending on option `deprecated`:
42
- const enableExpandElements = !isDeprecatedEnabled( options, 'noElementsExpansion' );
42
+ const enableExpandElements = !isDeprecatedEnabled( options, '_noElementsExpansion' );
43
43
  // TODO: we should get rid of noElementsExpansion soon; both
44
44
  // beta.nestedProjections and beta.universalCsn do not work with it.
45
45
 
@@ -95,15 +95,14 @@ function tweakAssocs( model ) {
95
95
  if (!target || target._service) // assoc to other service is OK
96
96
  return;
97
97
  if (!elem.$inferred) { // && !elem.target.$inferred
98
- // TODO: spec meeting 2021-01-22: no warning
99
- warning( 'assoc-target-not-in-service', [ elem.target.location, elem ],
100
- { target, '#': (elem._main.query ? 'select' : 'define') }, {
101
- std: 'Target $(TARGET) of association is outside any service', // not used
102
- // eslint-disable-next-line max-len
103
- define: 'Target $(TARGET) of explicitly defined association is outside any service',
104
- // eslint-disable-next-line max-len
105
- select: 'Target $(TARGET) of explicitly selected association is outside any service',
106
- } );
98
+ info( 'assoc-target-not-in-service', [ elem.target.location, elem ],
99
+ { target, '#': (elem._main.query ? 'select' : 'define') }, {
100
+ std: 'Target $(TARGET) of association is outside any service', // not used
101
+ // eslint-disable-next-line max-len
102
+ define: 'Target $(TARGET) of explicitly defined association is outside any service',
103
+ // eslint-disable-next-line max-len
104
+ select: 'Target $(TARGET) of explicitly selected association is outside any service',
105
+ } );
107
106
  }
108
107
  else {
109
108
  info( 'assoc-outside-service', [ elem.target.location, elem ],
@@ -31,6 +31,10 @@ function annotationVal( anno ) {
31
31
  function annotationIsFalse( anno ) { // falsy, but not null (unset)
32
32
  return anno && (anno.val === false || anno.val === 0 || anno.val === '');
33
33
  }
34
+ function annotationHasEllipsis( anno ) {
35
+ const { val } = anno || {};
36
+ return Array.isArray( val ) && val.some( v => v.literal === 'token' && v.val === '...' );
37
+ }
34
38
 
35
39
  /**
36
40
  * Set compiler-calculated annotation value.
@@ -381,6 +385,7 @@ module.exports = {
381
385
  pushLink,
382
386
  annotationVal,
383
387
  annotationIsFalse,
388
+ annotationHasEllipsis,
384
389
  annotateWith,
385
390
  setLink,
386
391
  setArtifactLink,
@@ -395,14 +395,14 @@ function csn2edmAll(_csn, _options, serviceNames=undefined) {
395
395
  {
396
396
  const EntityTypeName = entityCsn.name.replace(schemaNamePrefix, '');
397
397
  const EntitySetName = edmUtils.getBaseName(entityCsn.$entitySetName || entityCsn.name);
398
-
398
+ const isSingleton = edmUtils.isSingleton(entityCsn) && options.isV4();
399
399
  const [ properties, hasStream ] = createProperties(entityCsn);
400
400
 
401
401
  const loc = ['definitions', entityCsn.name];
402
402
  const type = `${schema.name}.${EntityTypeName}`;
403
403
  if(properties.length === 0)
404
404
  warning(null, loc, { type }, 'EDM EntityType $(TYPE) has no properties');
405
- else if(entityCsn.$edmKeyPaths.length === 0)
405
+ else if(entityCsn.$edmKeyPaths.length === 0 && !isSingleton)
406
406
  message('odata-spec-violation-no-key', loc);
407
407
 
408
408
  if(!edmUtils.isODataSimpleIdentifier(EntityTypeName))
@@ -688,9 +688,7 @@ function csn2edmAll(_csn, _options, serviceNames=undefined) {
688
688
  if(elementCsn._edmParentCsn == undefined)
689
689
  setProp(elementCsn, '_edmParentCsn', edmParentCsn);
690
690
 
691
- if(!elementCsn._ignore) {
692
- if(edmUtils.isAssociationOrComposition(elementCsn))
693
- {
691
+ if(edmUtils.isAssociationOrComposition(elementCsn)) {
694
692
  // Foreign keys are part of the generic elementCsn.elements property creation
695
693
 
696
694
  // This is the V4 edmx:NavigationProperty
@@ -698,36 +696,35 @@ function csn2edmAll(_csn, _options, serviceNames=undefined) {
698
696
 
699
697
  // suppress navprop creation only if @odata.navigable:false is not annotated.
700
698
  // (undefined !== false) still evaluates to true
701
- if (!elementCsn._target.abstract && elementCsn['@odata.navigable'] !== false)
699
+ if (!elementCsn._target.abstract && elementCsn['@odata.navigable'] !== false)
702
700
  {
703
- const navProp = new Edm.NavigationProperty(v, {
704
- Name: elementName,
705
- Type: elementCsn._target.name
706
- }, elementCsn);
707
- props.push(navProp);
701
+ const navProp = new Edm.NavigationProperty(v, {
702
+ Name: elementName,
703
+ Type: elementCsn._target.name
704
+ }, elementCsn);
705
+ props.push(navProp);
708
706
  // save the navProp in the global array for late constraint building
709
- navigationProperties.push(navProp);
710
- }
707
+ navigationProperties.push(navProp);
711
708
  }
709
+ }
712
710
  // render ordinary property if element is NOT ...
713
711
  // 1) ... annotated @cds.api.ignore
714
712
  // 2) ... annotated @odata.foreignKey4 and odataFormat: structured
715
713
 
716
- else if(isEdmPropertyRendered(elementCsn, options))
714
+ else if(isEdmPropertyRendered(elementCsn, options))
717
715
  {
718
716
  // CDXCORE-CDXCORE-173
719
717
  // V2: filter @Core.MediaType
720
- if ( options.isV2() && elementCsn['@Core.MediaType']) {
721
- hasStream = elementCsn['@Core.MediaType'];
722
- delete elementCsn['@Core.MediaType'];
718
+ if ( options.isV2() && elementCsn['@Core.MediaType']) {
719
+ hasStream = elementCsn['@Core.MediaType'];
720
+ delete elementCsn['@Core.MediaType'];
723
721
  // CDXCORE-CDXCORE-177:
724
722
  // V2: don't render element but add attribute 'm:HasStream="true' to EntityType
725
723
  // V4: render property type 'Edm.Stream'
726
- streamProps.push(elementName);
724
+ streamProps.push(elementName);
727
725
 
728
- } else {
729
- props.push(new Edm.Property(v, { Name: elementName }, elementCsn));
730
- }
726
+ } else {
727
+ props.push(new Edm.Property(v, { Name: elementName }, elementCsn));
731
728
  }
732
729
  }
733
730
 
@@ -54,6 +54,10 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
54
54
  fallBackSchemaName,
55
55
  whatsMyServiceRootName ] = getAnOverviewOnTheServices(csn);
56
56
 
57
+ if(serviceRootNames.length === 0) {
58
+ return [serviceRoots, Object.create(null), reqDefs, whatsMyServiceRootName, fallBackSchemaName, options];
59
+ }
60
+
57
61
  if(requestedServiceNames === undefined)
58
62
  requestedServiceNames = options.serviceNames;
59
63
  if(requestedServiceNames === undefined) {
@@ -64,10 +68,6 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
64
68
  return requestedServiceNames.includes(whatsMyServiceRootName(n));
65
69
  }
66
70
 
67
- if(serviceRootNames.length === 0) {
68
- return [serviceRoots, Object.create(null), reqDefs, whatsMyServiceRootName, fallBackSchemaName, options];
69
- }
70
-
71
71
  // Structural CSN inbound QA checks
72
72
  inboundQualificationChecks();
73
73
  // not needed at the moment
@@ -85,7 +85,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
85
85
 
86
86
  /*
87
87
  Final base type expansion is required here when:
88
- 1) The input CSN was already transformed for V4 but shall be rendered in V2 and the
88
+ 1) The input CSN was already transformed for V4 but shall be rendered in V2 and the
89
89
  edmx generator is called directly (bypassing OData transformation)
90
90
  2) The input CSN was already transformed for V4 and persisted (all non-enumerables are
91
91
  stripped of)
@@ -119,11 +119,6 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
119
119
  }
120
120
 
121
121
  if(schemaNames.length) {
122
- // First attach names to all definitions (and actions/params) in the model
123
- // elements are done in initializeStruct
124
- // Set myServiceName for later reference and indication of a service member
125
- // First attach names to all definitions in the model and fill reqDefs
126
- // Link association targets and spray @odata.contained over untagged compositions
127
122
  forEachDefinition(csn, [
128
123
  attachNameProperty,
129
124
  (def, defName) => {
@@ -307,7 +302,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
307
302
  const myServiceRoot = whatsMyServiceRootName(defName);
308
303
  const mySchemaPrefix = getSchemaPrefix(defName);
309
304
  if(myServiceRoot && options.isV4() &&
310
- /*(options.toOdata.odataProxies || options.toOdata.odataXServiceRefs) && options.isStructFormat && */
305
+ /*(options.odataProxies || options.odataXServiceRefs) && options.isStructFormat && */
311
306
  defName !== myServiceRoot && myServiceRoot !== mySchemaPrefix) {
312
307
  const service = { kind: 'service', name: mySchemaPrefix };
313
308
  serviceRoots[mySchemaPrefix] = service;
@@ -341,7 +336,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
341
336
  // link association target to association and add @odata.contained to compositions in V4
342
337
  function linkAssociationTarget(struct) {
343
338
  forEachMemberRecursively(struct, (element, name, prop, subpath) => {
344
- if(isAssociationOrComposition(element) && !element._ignore) {
339
+ if(isAssociationOrComposition(element)) {
345
340
  if(!element._target) {
346
341
  let target = csn.definitions[element.target];
347
342
  if(target) {
@@ -685,7 +680,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
685
680
  applyAppSpecificLateCsnTransformationOnElement(options, element, def, error);
686
681
  }, [], true, { elementsOnly: true });
687
682
 
688
- if(!isDeprecatedEnabled(options, 'v1KeysForTemporal')) {
683
+ if(!isDeprecatedEnabled(options, '_v1KeysForTemporal')) {
689
684
  // if artifact has a cds.valid.key mention it as @Core.AlternateKey
690
685
  if(validKey.length) {
691
686
  let altKeys = [{ Key: [] }];
@@ -738,7 +733,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
738
733
  forEachMemberRecursively(def.items || def, initConstraintsOnAssoc, [], true, { elementsOnly: true });
739
734
  }
740
735
  function initConstraintsOnAssoc(element) {
741
- if (isAssociationOrComposition(element) && !element._ignore && !element._constraints) {
736
+ if (isAssociationOrComposition(element) && !element._constraints) {
742
737
  // setup the constraints object
743
738
  setProp(element, '_constraints', { constraints: Object.create(null), selfs: [], _origins: [], termCount: 0 });
744
739
  // and crack the ON condition
@@ -790,7 +785,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
790
785
  delete struct.$keys[element.name];
791
786
  }
792
787
  }
793
- // deprecated unmanagedUpInComponent:
788
+ // deprecated._unmanagedUpInComponent:
794
789
  // Only in containment:
795
790
  // Ignore this (foreign key) elment if renderForeignKeys is false
796
791
  if(options.odataContainment && element['@odata.containment.ignore']) {
@@ -855,7 +850,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
855
850
  sub artifacts exposed by the initial type exposure
856
851
  */
857
852
  function convertExposedTypesOfOtherServicesIntoCrossReferences() {
858
- if(options.toOdata.odataXServiceRefs && options.isV4()) {
853
+ if(options.odataXServiceRefs && options.isV4()) {
859
854
  serviceRootNames.forEach(srn => {
860
855
  schemaNames.forEach(fqSchemaName => {
861
856
  if(fqSchemaName.startsWith(srn + '.')) {
@@ -912,7 +907,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
912
907
  // if this artifact is a service member check its associations
913
908
  if(globalSchemaPrefix) {
914
909
  forEachGeneric(struct.items || struct, 'elements', element => {
915
- if(!isAssociationOrComposition(element) || element._ignore || element['@odata.navigable'] === false)
910
+ if(!isAssociationOrComposition(element) || element['@odata.navigable'] === false)
916
911
  return;
917
912
  /*
918
913
  * Consider everything @cds.autoexpose: falsy to be a proxy candidate for now
@@ -949,18 +944,18 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
949
944
  const targetSchemaName = element._target.$mySchemaName;
950
945
  if(isProxyRequired(element)) {
951
946
  if(options.isV4() &&
952
- (options.toOdata.odataProxies || options.toOdata.odataXServiceRefs) &&
947
+ (options.odataProxies || options.odataXServiceRefs) &&
953
948
  // must be a managed association with keys OR an unambiguous backlink
954
- element.keys ||
949
+ element.keys ||
955
950
  (element.on && element._constraints.selfs.length === 1 && element._constraints.termCount === 1)
956
951
  ) {
957
952
  // reuse proxy if available
958
953
  let proxy = getProxyForTargetOf(element);
959
954
  if(!proxy) {
960
- if(targetSchemaName && options.toOdata.odataXServiceRefs) {
955
+ if(targetSchemaName && options.odataXServiceRefs) {
961
956
  proxy = createSchemaRefFor(targetSchemaName);
962
957
  }
963
- else if(options.toOdata.odataProxies) {
958
+ else if(options.odataProxies) {
964
959
  proxy = createProxyFor(element, targetSchemaName);
965
960
  }
966
961
  proxy = registerProxy(proxy, element);
@@ -1024,7 +1019,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
1024
1019
  // proxyDefinitionName: strip the serviceName and replace '.' with '_'
1025
1020
  let defName =
1026
1021
  `${assoc._target.name.replace(proxySchemaName + '.', '').replace(/\./g, '_')}`;
1027
-
1022
+
1028
1023
  // fullName: Prepend serviceName and if in same service add '_proxy'
1029
1024
  const proxy = isParamProxy
1030
1025
  ? createParameterEntity(assoc._target, proxySchemaName + '.' + defName, true)
@@ -1074,7 +1069,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
1074
1069
  if(!newElt) {
1075
1070
  if(csnUtils.isAssocOrComposition(e.type)) {
1076
1071
  if(!e.on && e.keys) {
1077
- if(options.toOdata.odataNoTransitiveProxies)
1072
+ if(options.odataNoTransitiveProxies)
1078
1073
  newElt = convertManagedAssocIntoStruct(e);
1079
1074
  else
1080
1075
  newElt = createProxyOrSchemaRefForManagedAssoc(e);
@@ -1275,10 +1270,10 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
1275
1270
  proxy = getProxyForTargetOf(e);
1276
1271
  if(!proxy) {
1277
1272
  // option odataXServiceRefs has precedence over odataProxies
1278
- if(e._target.$mySchemaName && options.toOdata.odataXServiceRefs) {
1273
+ if(e._target.$mySchemaName && options.odataXServiceRefs) {
1279
1274
  proxy = createSchemaRefFor(e._target.$mySchemaName);
1280
1275
  }
1281
- else if(options.toOdata.odataProxies) {
1276
+ else if(options.odataProxies) {
1282
1277
  proxy = createProxyFor(e, e._target.$mySchemaName);
1283
1278
  if(!e._target.$isParamEntity)
1284
1279
  populateProxyElements(e, proxy, getForeignKeyDefinitions(e));
@@ -1451,7 +1446,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
1451
1446
  if(def.$keys) {
1452
1447
  setProp(def, '$edmKeyPaths', []);
1453
1448
  // for all key elements that shouldn't be ignored produce the paths
1454
- foreach(def.$keys, k => !k._ignore && !(k._isToContainer && k._selfReferences.length), (k, kn) => {
1449
+ foreach(def.$keys, k => !(k._isToContainer && k._selfReferences.length), (k, kn) => {
1455
1450
  if(isEdmPropertyRendered(k, options) &&
1456
1451
  !(options.isV2() && k['@Core.MediaType'])) {
1457
1452
  if(options.isV4() && options.isStructFormat) {
@@ -1922,7 +1917,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
1922
1917
  if(Object.keys(o).length) {
1923
1918
  // ReadRestrictions may have sub type ReadByKeyRestrictions { Description, LongDescription }
1924
1919
  // chop annotations into dictionaries
1925
- if(prefix === '@Capabilities.ReadRestrictions' &&
1920
+ if(prefix === '@Capabilities.ReadRestrictions' &&
1926
1921
  Object.keys(o).some(k => k.startsWith('ReadByKeyRestrictions.'))) {
1927
1922
  const no = {};
1928
1923
  Object.entries(o).forEach(([k,v]) => {
@@ -1964,15 +1959,15 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
1964
1959
 
1965
1960
  function mapCdsToEdmProp(obj) {
1966
1961
  if (obj.type && isBuiltinType(obj.type) && !isAssociationOrComposition(obj) && !obj.targetAspect) {
1967
- let edmType = edmUtils.mapCdsToEdmType(obj, messageFunctions, _options.toOdata.version === 'v2', obj['@Core.MediaType']);
1962
+ let edmType = edmUtils.mapCdsToEdmType(obj, messageFunctions, _options.odataVersion === 'v2', obj['@Core.MediaType']);
1968
1963
  assignProp(obj, '_edmType', edmType);
1969
1964
  } else if (obj._isCollection && (obj.items && isBuiltinType(csnUtils.getFinalTypeDef(obj.items.type)))) {
1970
- let edmType = edmUtils.mapCdsToEdmType(obj.items, messageFunctions, _options.toOdata.version === 'v2', obj['@Core.MediaType'], obj.$path);
1965
+ let edmType = edmUtils.mapCdsToEdmType(obj.items, messageFunctions, _options.odataVersion === 'v2', obj['@Core.MediaType'], obj.$path);
1971
1966
  assignProp(obj, '_edmType', edmType);
1972
1967
  }
1973
1968
  // This is the special case when we have array of array, but will not be supported in the future
1974
1969
  else if (obj._isCollection && obj.items && obj.items.type && obj.items.items && isBuiltinType(csnUtils.getFinalTypeDef(obj.items.items.type))) {
1975
- let edmType = edmUtils.mapCdsToEdmType(obj.items.items, messageFunctions, _options.toOdata.version === 'v2', obj['@Core.MediaType']);
1970
+ let edmType = edmUtils.mapCdsToEdmType(obj.items.items, messageFunctions, _options.odataVersion === 'v2', obj['@Core.MediaType']);
1976
1971
  assignProp(obj, '_edmType', edmType);
1977
1972
  }
1978
1973
  }
@@ -8,31 +8,17 @@ function validateOptions(_options)
8
8
  {
9
9
  if(!_options.isV2 && !_options.isV4)
10
10
  {
11
- // csn2edm expects "version" to be a top-level property of options
11
+ // csn2edm expects "odataVersion" to be a top-level property of options
12
12
  // set to 'v4' as default, override with value from incoming options
13
- // (here version comes inside "toOdata")
14
- const options = Object.assign({ version: 'v4'}, _options);
15
- if (options.toOdata) {
16
- if(options.toOdata.version)
17
- options.version = options.toOdata.version;
18
- if(options.toOdata.odataFormat)
19
- options.odataFormat = options.toOdata.odataFormat;
20
- if(options.toOdata.odataContainment)
21
- options.odataContainment = options.toOdata.odataContainment;
22
- if(options.toOdata.odataForeignKeys)
23
- options.odataForeignKeys = options.toOdata.odataForeignKeys;
24
- if(options.toOdata.odataV2PartialConstr)
25
- options.odataV2PartialConstr = options.toOdata.odataV2PartialConstr;
26
- // global flag that indicates whether or not FKs shall be rendered in general
27
- // V2/V4 flat: yes
28
- // V4/struct: depending on odataForeignKeys
29
- options.renderForeignKeys =
30
- options.version === 'v4' ? options.odataFormat === 'structured' && !!options.odataForeignKeys : true;
31
-
32
- }
33
-
34
- const v2 = options.version.match(/v2/i) !== null;
35
- const v4 = options.version.match(/v4/i) !== null;
13
+ const options = Object.assign({ odataVersion: 'v4'}, _options);
14
+ // global flag that indicates whether or not FKs shall be rendered in general
15
+ // V2/V4 flat: yes
16
+ // V4/struct: depending on odataForeignKeys
17
+ options.renderForeignKeys =
18
+ options.odataVersion === 'v4' ? options.odataFormat === 'structured' && !!options.odataForeignKeys : true;
19
+
20
+ const v2 = options.odataVersion.match(/v2/i) !== null;
21
+ const v4 = options.odataVersion.match(/v4/i) !== null;
36
22
 
37
23
  options.v = [v2, v4];
38
24
  options.isStructFormat = options.odataFormat && options.odataFormat === 'structured';
@@ -1 +1 @@
1
- 351a6ed427f91f2eef4d8e9a2e11dd17
1
+ dd18d05cabbe93eabf1bd17b83add5ee