@sap/cds-dk 4.6.4 → 4.8.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 (74) hide show
  1. package/CHANGELOG.md +68 -1
  2. package/bin/activate.js +5 -1
  3. package/bin/add.js +2 -1
  4. package/bin/bind.js +121 -48
  5. package/bin/cds.js +8 -0
  6. package/bin/env.js +0 -2
  7. package/bin/repl.js +5 -2
  8. package/bin/watch.js +10 -7
  9. package/lib/bind/bindingResolver.js +26 -14
  10. package/lib/bind/bindingUtil.js +144 -0
  11. package/lib/bind/cfKeyProvider.js +2 -80
  12. package/lib/bind/kubernetesCredentialsProvider.js +157 -0
  13. package/lib/bind/userCdsrcJsonStorageProvider.js +7 -7
  14. package/lib/client/activate.js +16 -13
  15. package/lib/client/base_command.js +5 -1
  16. package/lib/client/helper/cf_helper.js +5 -2
  17. package/lib/client/params.js +16 -2
  18. package/lib/client/settings_manager.js +15 -8
  19. package/lib/compile/openapi/csdl2openapi.js +6 -8
  20. package/lib/compile/to-xsuaa.js +0 -14
  21. package/lib/import/utils/MetadataConverter.js +6 -4
  22. package/lib/import/utils/MultiMap.js +1 -0
  23. package/lib/import/v2parser.js +150 -64
  24. package/lib/import/v4parser.js +118 -56
  25. package/lib/index.js +6 -5
  26. package/lib/init/constants.js +11 -5
  27. package/lib/init/index.js +14 -7
  28. package/lib/init/template/_merging/existences.js +161 -0
  29. package/lib/init/template/approuter/files/default-env.json +9 -0
  30. package/lib/init/template/approuter/files/mta.yaml.hbs +48 -0
  31. package/lib/init/template/approuter/files/package.json +9 -0
  32. package/lib/init/template/approuter/files/xs-app.json +8 -0
  33. package/lib/init/template/approuter/index.js +66 -0
  34. package/lib/init/template/auditlog/files/dependencies.package.json +5 -0
  35. package/lib/init/template/auditlog/files/mta.yaml.hbs +13 -0
  36. package/lib/init/template/auditlog/index.js +38 -0
  37. package/lib/init/template/cf-manifest/index.js +1 -1
  38. package/lib/init/template/data/index.js +18 -6
  39. package/lib/init/template/hana/files/common/undeploy.json +5 -0
  40. package/lib/init/template/hana/files/java/package.json +3 -0
  41. package/lib/init/template/hana/files/mta.yaml.hbs +42 -0
  42. package/lib/init/template/hana/files/nodejs/dependencies.package.json +5 -0
  43. package/lib/init/template/hana/index.js +53 -24
  44. package/lib/init/template/java/index.js +1 -5
  45. package/lib/init/template/lint/index.js +17 -1
  46. package/lib/init/template/mta/files/mta.yaml.hbs +27 -216
  47. package/lib/init/template/mta/index.js +25 -17
  48. package/lib/init/template/mtx/files/cds.package.json +24 -0
  49. package/lib/init/template/mtx/files/dependencies.package.json +5 -0
  50. package/lib/init/template/mtx/files/mta.yaml.hbs +74 -0
  51. package/lib/init/template/mtx/files/xs-security.json.hbs +23 -9
  52. package/lib/init/template/mtx/index.js +126 -29
  53. package/lib/init/template/templateBase.js +14 -0
  54. package/lib/init/template/xsuaa/files/cds.package.json +9 -0
  55. package/lib/init/template/xsuaa/files/dependencies.package.json +6 -0
  56. package/lib/init/template/xsuaa/files/mta.yaml.hbs +17 -0
  57. package/lib/init/template/xsuaa/index.js +75 -0
  58. package/lib/init/util/fsUtil.js +18 -4
  59. package/lib/init/util/logger.js +3 -1
  60. package/lib/init/util/mvnArchetypeUtil.js +3 -1
  61. package/lib/init/{template/mta → util}/projectReader.js +26 -11
  62. package/lib/init/util/templateUtil.js +267 -3
  63. package/lib/lint/Linter.js +1 -2
  64. package/lib/lint/io.js +3 -12
  65. package/lib/util/exec.d.ts +54 -0
  66. package/lib/util/exec.js +210 -0
  67. package/lib/watch/livereload-server.js +43 -31
  68. package/lib/watch/node-watch.js +46 -20
  69. package/lib/watch/open.js +1 -1
  70. package/npm-shrinkwrap.json +3382 -9106
  71. package/package.json +8 -9
  72. package/readme.md +1 -1
  73. package/lib/init/template/mtx/package/cds.package.json +0 -29
  74. package/lib/init/template/mtx/package/dependencies.package.json +0 -9
@@ -9,6 +9,7 @@ let allEntities = [];
9
9
  let allEntitiesMC = [];
10
10
  let allEntitySetMap = {};
11
11
  let allEntitySetMapMC = {};
12
+ let allEntitySetNamespaces = {};
12
13
  let allFunctionImports = [];
13
14
  let allFunctionImportsMap = {};
14
15
  let allAssociations = {};
@@ -22,6 +23,7 @@ let allowAllNamespaces = false;
22
23
  let messages = require("./message").getMessages();
23
24
  let common = require("./common");
24
25
  let versionInfo = require('../../package.json').version;
26
+ const { warn } = require('@sap/cds/bin/utils/term');
25
27
 
26
28
  let edmxncdsdatatype = {
27
29
  "Edm.String": "cds.LargeString",
@@ -30,15 +32,14 @@ let edmxncdsdatatype = {
30
32
  "Edm.Int32": "cds.Integer",
31
33
  "Edm.Int64": "cds.Integer64",
32
34
  "Edm.Decimal": "cds.DecimalFloat",
33
- "Edm.DateTime": "cds.DateTime",
34
- "Edm.DateTimeOffset": "cds.Timestamp",
35
+ "Edm.DateTime": "cds.DateTime",
36
+ "Edm.DateTimeOffset": "cds.DateTime",
35
37
  "Edm.Time": "cds.Time",
36
38
  "Edm.Binary": "cds.LargeBinary",
37
39
  "Edm.Guid": "cds.UUID",
38
40
  "Edm.Byte": "cds.Integer",
39
41
  "Edm.SByte": "cds.Integer",
40
42
  "Edm.Double": "cds.Double",
41
- "Edm.Single": "cds.DecimalFloat",
42
43
  // Special handling of data types
43
44
  "Edm.String_m": "cds.String", // Max length
44
45
  "Edm.Decimal_p": "cds.Decimal", // Precision, scale
@@ -47,6 +48,11 @@ let edmxncdsdatatype = {
47
48
  "Edm.Binary_m": "cds.Binary", // Max Length
48
49
  "Edm.Byte_m": "cds.Integer", // Max Length
49
50
  "Edm.Double_p": "cds.Double", // Precision, scale
51
+ // Special handling with annotations
52
+ "Edm.Single_a": "cds.Double",
53
+ "Edm.Stream_a" : "cds.LargeBinary",
54
+ "Edm.DateTimeOffset_a" : "cds.Timestamp", //precision > 0
55
+ "Edm.DateTime_a" : "cds.Timestamp" //precision > 0
50
56
  };
51
57
 
52
58
  function _initialize() {
@@ -243,6 +249,9 @@ function _extractEntityFromEntitySet(entitySet) {
243
249
  allEntitySetMapMC[entitySet[key].EntityType] = [];
244
250
  allEntitySetMapMC[entitySet[key].EntityType].push(entitySet[key].Name);
245
251
  entityName = _extractEntityFromNamespace(entitySet[key].EntityType);
252
+ let namespaces = namespaceAttributeFilter(entitySet[key]);
253
+ if(namespaces.length)
254
+ allEntitySetNamespaces[entitySet[key].Name] = namespaces;
246
255
  allEntities.push(entityName);
247
256
  allEntitiesMC.push(entitySet[key].Name);
248
257
  }
@@ -409,9 +418,16 @@ function _getServiceEntityProperty(
409
418
  displayFormat,
410
419
  isKey,
411
420
  documentation,
412
- isCollection,
413
421
  allowedNamespaceAttributes = -1
414
422
  ) {
423
+ let isCollection = -1;
424
+ //preprocessing of datatype in case it is a collection
425
+ if(dataType.substring(0,10) === 'Collection')
426
+ {
427
+ dataType = dataType.substring(11,dataType.length-1);
428
+ isCollection = 1;
429
+ }
430
+
415
431
  let cdsDataType = null;
416
432
  let hasInvalidPrecision = false;
417
433
  let propertyJson='';
@@ -420,8 +436,9 @@ function _getServiceEntityProperty(
420
436
  } else if (precision && precision > 0) {
421
437
  cdsDataType = edmxncdsdatatype[dataType + "_p"];
422
438
  // Falling back to actual data type as precision has no meaning for 'Date' related data types
439
+ // Using _a data type if precision is there for 'Date' related data types
423
440
  if (cdsDataType === undefined) {
424
- cdsDataType = edmxncdsdatatype[dataType];
441
+ cdsDataType = edmxncdsdatatype[dataType + "_a"];
425
442
  hasInvalidPrecision = true;
426
443
  }
427
444
  } else if (displayFormat && displayFormat === "Date") {
@@ -430,6 +447,10 @@ function _getServiceEntityProperty(
430
447
  cdsDataType = edmxncdsdatatype[dataType];
431
448
  }
432
449
 
450
+ //checks if it's an annotation case
451
+ if (!cdsDataType) {
452
+ cdsDataType = edmxncdsdatatype[dataType + "_a"];
453
+ }
433
454
  // Lookup from complex type properties
434
455
  if (!cdsDataType && allComplexTypes[dataType]) {
435
456
  cdsDataType = dataType;
@@ -442,11 +463,23 @@ function _getServiceEntityProperty(
442
463
 
443
464
  //Possibility of entity type or entity set as the data type
444
465
  if (!cdsDataType && allEntitySetMapMC[dataType]) {
445
- cdsDataType = serviceNamespace + "." + allEntitySetMapMC[dataType];
466
+ cdsDataType = serviceNamespace + "." + allEntitySetMapMC[dataType][0];
446
467
  } else if(!cdsDataType && allEntitySetMap[_extractEntityFromNamespace(dataType)]) {
447
468
  cdsDataType = dataType;
448
469
  }
449
470
 
471
+ //if the cdsDataType is undefined/ not supported
472
+ if(cdsDataType === undefined)
473
+ {
474
+ let message = '"' + dataType + '" is not supported';
475
+ if(propertyName)
476
+ message += ' (in element:"' + propertyName + '")';
477
+ else
478
+ message += ' (in return type)'
479
+ console.log(warn(message));
480
+ return "";
481
+ }
482
+
450
483
  if(propertyName)
451
484
  propertyJson = '"' + propertyName + '": {\n';
452
485
 
@@ -458,6 +491,13 @@ function _getServiceEntityProperty(
458
491
  propertyJson = propertyJson + '"items": { \n'
459
492
  }
460
493
  propertyJson = propertyJson + '"type":"' + cdsDataType + '"';
494
+
495
+ //if annotations to be added
496
+ if(edmxncdsdatatype[dataType + "_a"] && cdsDataType != "cds.Date")
497
+ {
498
+ propertyJson = propertyJson + ',\n"@odata.type": "' + dataType + '"';
499
+ }
500
+
461
501
  if (length && length > 0) {
462
502
  propertyJson = propertyJson + ',\n"length":' + length;
463
503
  } else if (precision && precision > 0 && hasInvalidPrecision === false) {
@@ -468,6 +508,14 @@ function _getServiceEntityProperty(
468
508
  propertyJson = propertyJson + ',\n"scale":' + 0;
469
509
  }
470
510
  }
511
+
512
+ //adding precision in case of DateTime datatypes
513
+ if((dataType === "Edm.DateTimeOffset" || dataType === "Edm.DateTime") && cdsDataType != "cds.Date")
514
+ {
515
+ if(!precision || precision === -1) precision = 0;
516
+ propertyJson = propertyJson + ',\n"@odata.precision": ' + precision;
517
+ }
518
+
471
519
  if(isCollection === 1)
472
520
  {
473
521
  propertyJson = propertyJson + '\n}'
@@ -503,12 +551,10 @@ function _getServiceComplexType(complexTypeKey, complexType) {
503
551
  complexTypeProperty = complexType[i]._attributes;
504
552
  if(complexType[i].Documentation)
505
553
  complexTypeProperty.doc = _parseDocumentationTag(complexType[i].Documentation);
506
-
507
554
  let namespaceAttributes = namespaceAttributeFilter(complexTypeProperty)
508
555
  const complexTypePropertyNamespace = namespaceAttributes.length ? namespaceAttributes : -1
509
556
 
510
- complexTypeCSN =
511
- complexTypeCSN +
557
+ let complexProperty =
512
558
  _getServiceEntityProperty(
513
559
  complexTypeProperty.Name,
514
560
  complexTypeProperty.Type,
@@ -518,10 +564,10 @@ function _getServiceComplexType(complexTypeKey, complexType) {
518
564
  complexTypeProperty["sap:display-format"],
519
565
  false,
520
566
  complexTypeProperty.doc,
521
- -1,
522
567
  complexTypePropertyNamespace
523
568
  );
524
- if (i !== complexType.length - 1) {
569
+ complexTypeCSN = complexTypeCSN + complexProperty;
570
+ if (i !== complexType.length - 1 && complexProperty != "") {
525
571
  complexTypeCSN = complexTypeCSN + ",\n";
526
572
  } else {
527
573
  complexTypeCSN = complexTypeCSN + "\n";
@@ -547,10 +593,13 @@ function _getServiceComplexType(complexTypeKey, complexType) {
547
593
  complexTypeProperty["sap:display-format"],
548
594
  false,
549
595
  complexTypeProperty.doc,
550
- -1,
551
596
  complexTypePropertyNamespace
552
597
  );
553
598
  }
599
+
600
+ if (complexTypeCSN && (complexTypeCSN.endsWith(",\n") || complexTypeCSN.endsWith(",\n\n"))) {
601
+ complexTypeCSN = complexTypeCSN.substring(0, complexTypeCSN.lastIndexOf(",\n")) + "\n";
602
+ }
554
603
  }
555
604
  complexTypeCSN = complexTypeCSN + "}\n";
556
605
  if (allInheritedComplexTypes[complexTypeKey]) {
@@ -590,41 +639,35 @@ function _parseParameter(parameter)
590
639
  {
591
640
  let csn = "";
592
641
  let doc;
593
- let isCollection = -1;
594
642
  if(parameter.Documentation)
595
643
  doc = _parseDocumentationTag(parameter.Documentation);
596
644
 
597
645
  let namespaceAttributes = namespaceAttributeFilter(parameter._attributes);
598
646
  const parameterNamespaceAttributes = namespaceAttributes.length ? namespaceAttributes : -1;
599
647
 
600
- let type = parameter["_attributes"].Type;
601
- if(type.substring(0,10) === 'Collection')
602
- {
603
- type = type.substring(11,type.length-1);
604
- isCollection = 1;
605
- }
606
648
  csn = csn + _getServiceEntityProperty(parameter["_attributes"].Name,
607
- type,
649
+ parameter["_attributes"].Type,
608
650
  parameter["_attributes"].MaxLength,
609
651
  parameter["_attributes"].Precision,
610
652
  parameter["_attributes"].Scale,
611
653
  parameter["_attributes"]["sap:display-format"],
612
654
  false,
613
655
  doc,
614
- isCollection,
615
656
  parameterNamespaceAttributes);
616
657
  return csn;
617
658
  }
618
659
 
619
660
  function _parseParametersFunctionImport(parameters, isBounded) {
620
661
  let csn = "";
662
+ let parameterCsn = "";
621
663
  let i = isBounded===1 ? 1 : 0;
622
664
  if(parameters.length)
623
665
  {
624
666
  for(i;i<parameters.length;i++)
625
667
  {
626
- csn = csn + _parseParameter(parameters[i]);
627
- if(i!== parameters.length - 1) {
668
+ parameterCsn = _parseParameter(parameters[i]);
669
+ csn = csn + parameterCsn;
670
+ if(i!== parameters.length - 1 && parameterCsn != "") {
628
671
  csn = csn + ",\n";
629
672
  } else {
630
673
  csn = csn + "\n";
@@ -634,6 +677,9 @@ function _parseParametersFunctionImport(parameters, isBounded) {
634
677
  csn = csn + _parseParameter(parameters);
635
678
  }
636
679
 
680
+ if (csn && (csn.endsWith(",\n") || csn.endsWith(",\n\n"))) {
681
+ csn= csn.substring(0, csn.lastIndexOf(",\n")) + "\n";
682
+ }
637
683
  return csn;
638
684
  }
639
685
 
@@ -648,31 +694,37 @@ function _getFunctionImport(functionImport,isBounded) {
648
694
  } else if(functionImport[1] === "POST")
649
695
  {
650
696
  csn = csn + "action";
697
+ } else {
698
+ let message = functionImport[0].substring(functionImport[0].lastIndexOf(".") + 1) + " has kind " + functionImport[1] + " which is not supported.";
699
+ console.log(warn(message));
700
+ return "";
651
701
  }
652
702
  csn = csn + '"';
653
703
  if(functionImport[3] !== -1)
654
704
  {
655
705
  if(isBounded === 0 || (isBounded === 1 && functionImport[3] instanceof Array ))
656
706
  {
657
- csn = csn + ", \n";
658
- csn = csn + '"params": { \n';
659
- csn = csn + _parseParametersFunctionImport(functionImport[3],isBounded);
660
- csn = csn + '\n }';
707
+ let parametersCsn = _parseParametersFunctionImport(functionImport[3],isBounded);
708
+ if(parametersCsn != "")
709
+ {
710
+ csn = csn + ", \n";
711
+ csn = csn + '"params": { \n';
712
+ csn = csn + _parseParametersFunctionImport(functionImport[3],isBounded);
713
+ csn = csn + '\n }';
714
+ }
661
715
  }
662
716
  }
663
717
  if(functionImport[2] !== -1)
664
718
  {
665
- csn = csn + ", \n";
666
- csn = csn + '"returns": { \n';
667
- let isCollection = -1;
668
- if(functionImport[2].substring(0,10) === 'Collection')
719
+ let returnCsn = _getServiceEntityProperty(noValue,functionImport[2],noValue,noValue,noValue,noValue,noValue,noValue);
720
+ if(returnCsn != "")
669
721
  {
670
- functionImport[2] = functionImport[2].substring(11,functionImport[2].length-1);
671
- isCollection = 1;
722
+ csn = csn + ", \n";
723
+ csn = csn + '"returns": { \n';
724
+ //return type
725
+ csn = csn + returnCsn;
726
+ csn = csn + '\n }';
672
727
  }
673
- //return type
674
- csn = csn + _getServiceEntityProperty(noValue,functionImport[2],noValue,noValue,noValue,noValue,noValue,noValue,isCollection);
675
- csn = csn + '\n }';
676
728
  }
677
729
  if(functionImport[4] !== -1 && functionImport[4])
678
730
  {
@@ -684,21 +736,25 @@ function _getFunctionImport(functionImport,isBounded) {
684
736
  }
685
737
 
686
738
  function _getAllFunctionImports(functionImports,isBounded) {
687
- let functionImportCSN = "";
739
+ let functionImportsCSN = "";
688
740
  let i;
741
+ let functionImportCSN = "";
689
742
  for(i=0; i<functionImports.length;i++)
690
743
  {
691
- functionImportCSN =
692
- functionImportCSN +
693
- _getFunctionImport(functionImports[i],isBounded);
694
- if(i!== functionImports.length - 1) {
695
- functionImportCSN = functionImportCSN + ",\n";
744
+ functionImportCSN = _getFunctionImport(functionImports[i],isBounded);
745
+ functionImportsCSN = functionImportsCSN + functionImportCSN;
746
+ if(i!== functionImports.length - 1 && functionImportCSN !== "" ) {
747
+ functionImportsCSN = functionImportsCSN + ",\n";
696
748
  } else {
697
- functionImportCSN = functionImportCSN + "\n";
749
+ functionImportsCSN = functionImportsCSN + "\n";
698
750
  }
699
751
  }
700
752
 
701
- return functionImportCSN;
753
+ //if last function import is omitted, remove the extra characters
754
+ if (functionImportsCSN && (functionImportsCSN.endsWith(",\n") || functionImportsCSN.endsWith(",\n\n"))) {
755
+ functionImportsCSN= functionImportsCSN.substring(0, functionImportsCSN.lastIndexOf(",\n")) + "\n";
756
+ }
757
+ return functionImportsCSN;
702
758
  }
703
759
 
704
760
  function _getEntityName(entity) {
@@ -830,8 +886,7 @@ function _generateCSNEntityKeys(entityKeysList, entityPropertiesMap) {
830
886
  let i;
831
887
  for (i = 0; i < entityKeysList.length; i++) {
832
888
  propAttributes = entityPropertiesMap[entityKeysList[i]];
833
- csnEntity =
834
- csnEntity +
889
+ let keyCsn =
835
890
  _getServiceEntityProperty(
836
891
  entityKeysList[i],
837
892
  propAttributes[0],
@@ -841,13 +896,16 @@ function _generateCSNEntityKeys(entityKeysList, entityPropertiesMap) {
841
896
  propAttributes[4],
842
897
  true,
843
898
  propAttributes[5],
844
- -1,
845
899
  propAttributes[6]
846
900
  );
847
- if (i !== entityKeysList.length - 1) {
901
+ csnEntity = csnEntity + keyCsn;
902
+ if (i !== entityKeysList.length - 1 && keyCsn != "") {
848
903
  csnEntity = csnEntity + ",\n";
849
904
  }
850
905
  }
906
+ if (csnEntity && (csnEntity.endsWith(",\n") || csnEntity.endsWith(",\n\n"))) {
907
+ csnEntity= csnEntity.substring(0, csnEntity.lastIndexOf(",\n")) + "\n";
908
+ }
851
909
  return csnEntity;
852
910
  }
853
911
 
@@ -869,8 +927,7 @@ function _generateCSNEntityProperties(entityKeysList, entityPropertiesMap) {
869
927
  // Include Property which are not part of keys
870
928
  if (entityKeysList.indexOf(property) === -1) {
871
929
  propAttributes = entityPropertiesMap[property];
872
- csnEntity =
873
- csnEntity +
930
+ let propertyString =
874
931
  _getServiceEntityProperty(
875
932
  property,
876
933
  propAttributes[0],
@@ -880,10 +937,10 @@ function _generateCSNEntityProperties(entityKeysList, entityPropertiesMap) {
880
937
  propAttributes[4],
881
938
  false,
882
939
  propAttributes[5],
883
- -1,
884
940
  propAttributes[6]
885
941
  );
886
- if (i !== entityProperties.length - 1) {
942
+ csnEntity = csnEntity + propertyString;
943
+ if (i !== entityProperties.length - 1 && propertyString != "") {
887
944
  csnEntity = csnEntity + ",\n";
888
945
  } else {
889
946
  csnEntity = csnEntity + "\n";
@@ -891,7 +948,9 @@ function _generateCSNEntityProperties(entityKeysList, entityPropertiesMap) {
891
948
  }
892
949
  }
893
950
  // Last property can be an key; eliminate additional delimiter.
894
- if (csnEntity && csnEntity.endsWith(",\n")) {
951
+ // Last property can have undefined datatype and be ignored too
952
+ //doubt
953
+ if (csnEntity && (csnEntity.endsWith(",\n") || csnEntity.endsWith(",\n\n"))) {
895
954
  csnEntity = csnEntity.substring(0, csnEntity.lastIndexOf(",\n")) + "\n";
896
955
  }
897
956
  return csnEntity;
@@ -1179,12 +1238,11 @@ function _getServiceEntityNavigationProperty(navPropAttributes, mockServerUc) {
1179
1238
  if(allowedNamespaceAttributes.length) {
1180
1239
  csn += _generateNamespaceAttributes(allowedNamespaceAttributes, false);
1181
1240
  }
1182
- // if documentatin exists for navigation property
1183
- if (navPropDoc) {
1184
- csn = csn + '"doc":' + `"Please add an ON condition\\n${navPropDoc}",\n`;
1185
- } else {
1186
- csn = csn + '"doc": "Please add an ON condition", \n';
1187
- }
1241
+ // annotation for on conditions
1242
+ csn = csn + `"@cds.ambiguous": "missing on condition?",\n`;
1243
+ // if documentation exists for navigation property
1244
+ if (navPropDoc)
1245
+ csn = csn + '"doc":' + ` "${navPropDoc}",\n`;
1188
1246
  csn = csn + '"type": "cds.Association",\n';
1189
1247
  csn = csn +
1190
1248
  _getCSNAssociatedEntitySet(
@@ -1249,6 +1307,8 @@ function _constructServiceEntity(
1249
1307
  mockServerUc,
1250
1308
  documentation
1251
1309
  ) {
1310
+ let filteredNamespaces = {};
1311
+ let namespaces = [];
1252
1312
  let serviceEntityName = serviceNamespaceParam + "." + entityName;
1253
1313
  let csnEntity = '"' + serviceEntityName + '": {\n';
1254
1314
  let csnKeys;
@@ -1265,10 +1325,29 @@ function _constructServiceEntity(
1265
1325
  csnEntity = csnEntity + '"abstract": true,\n';
1266
1326
  }
1267
1327
 
1268
- if(entityAttributes.allowedNamespaceAttributes.length)
1269
- {
1270
- csnEntity += _generateNamespaceAttributes(entityAttributes.allowedNamespaceAttributes, false);
1328
+ /* Merging the namespace list from entity set and entity type
1329
+ And in case of same label, entity set's value will have precedence */
1330
+ if(allEntitySetNamespaces[entityName]){
1331
+ allEntitySetNamespaces[entityName].forEach((item) => {
1332
+ filteredNamespaces[Object.keys(item)[0]] = Object.values(item)[0];
1333
+ });
1271
1334
  }
1335
+ if(entityAttributes.allowedNamespaceAttributes.length){
1336
+ entityAttributes.allowedNamespaceAttributes.forEach((item) => {
1337
+ if(!filteredNamespaces[Object.keys(item)[0]]){
1338
+ filteredNamespaces[Object.keys(item)[0]] = Object.values(item)[0];
1339
+ }
1340
+ });
1341
+ }
1342
+ Object.keys(filteredNamespaces).forEach((item) => {
1343
+ let obj = {};
1344
+ obj[item] = filteredNamespaces[item];
1345
+ namespaces.push(obj)
1346
+ });
1347
+
1348
+ if(namespaces)
1349
+ csnEntity += _generateNamespaceAttributes(namespaces, false);
1350
+
1272
1351
  // if documentation exists for the entity
1273
1352
  if (documentation) {
1274
1353
  csnEntity = csnEntity + `"doc": "${documentation}",` + '\n';
@@ -1277,13 +1356,18 @@ function _constructServiceEntity(
1277
1356
 
1278
1357
  // Key Entity attributes
1279
1358
  csnKeys = _generateCSNEntityKeys(entityKeysList, entityPropertiesMap);
1280
- csnEntity = csnEntity + csnKeys;
1281
1359
 
1282
1360
  // Non key Entity attributes
1283
1361
  csnProperties = _generateCSNEntityProperties(
1284
1362
  entityKeysList,
1285
1363
  entityPropertiesMap
1286
1364
  );
1365
+ csnProperties = csnKeys + csnProperties;
1366
+ //to remove additional ',\n' in case key datatype is undefined
1367
+ if (csnProperties && csnProperties.startsWith(",\n")) {
1368
+ csnProperties = csnProperties.substring(csnProperties.indexOf(",\n") + 2);
1369
+ }
1370
+
1287
1371
  csnEntity = csnEntity + csnProperties;
1288
1372
 
1289
1373
  // No keys and No properties found
@@ -1501,13 +1585,15 @@ function _generateEDMXJSON2CSN(
1501
1585
 
1502
1586
  if (mockServerUc) {
1503
1587
  let def = '"' + serviceNamespaceParam + '": {"kind": "service"' + ',\n' + '"@cds.external": true';
1504
-
1505
1588
  let serviceDoc = jsonObj["edmx:Edmx"]["edmx:DataServices"]["Schema"].EntityContainer.Documentation;
1589
+ let namespaceAttributes = namespaceAttributeFilter(jsonObj["edmx:Edmx"]["edmx:DataServices"]["Schema"].EntityContainer["_attributes"]);
1506
1590
  // if documentation exists for service
1507
1591
  if (serviceDoc) {
1508
1592
  let doc = _parseDocumentationTag(serviceDoc);
1509
1593
  if (doc) def += ',\n' + `"doc": "${doc}"`;
1510
1594
  }
1595
+ if(namespaceAttributes.length)
1596
+ def += _generateNamespaceAttributes(namespaceAttributes,true);
1511
1597
  def += "}";
1512
1598
  definitions.push(def);
1513
1599
  }