@sap/cds-dk 6.2.3 → 6.3.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 (70) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/bin/bind.js +4 -4
  3. package/bin/deploy/to-h2.js +4 -0
  4. package/bin/deploy/to-sqlite.js +6 -4
  5. package/bin/help.js +1 -1
  6. package/bin/login.js +1 -0
  7. package/bin/push.js +29 -7
  8. package/lib/bind/userCdsrcJsonStorageProvider.js +4 -4
  9. package/lib/client/activate.js +1 -1
  10. package/lib/client/base_command.js +10 -10
  11. package/lib/client/helper/dependency_helper.js +10 -1
  12. package/lib/client/helper/logging.js +6 -2
  13. package/lib/client/pull.js +6 -6
  14. package/lib/client/push.js +33 -14
  15. package/lib/client/settings_manager.js +52 -21
  16. package/lib/compile/openapi/csdl2openapi.js +1 -1
  17. package/lib/compile/to-xsuaa.js +1 -1
  18. package/lib/import/odata/v2parser.js +37 -1
  19. package/lib/import/odata/v4parser.js +101 -23
  20. package/lib/init/constants.js +1 -1
  21. package/lib/init/index.js +23 -45
  22. package/lib/init/template/approuter/index.js +44 -48
  23. package/lib/init/template/auditlog/index.js +14 -10
  24. package/lib/init/template/cf-manifest/index.js +9 -11
  25. package/lib/init/template/connectivity/index.js +10 -10
  26. package/lib/init/template/data/index.js +20 -19
  27. package/lib/init/template/destinations/index.js +14 -9
  28. package/lib/init/template/enterprise-messaging/index.js +14 -9
  29. package/lib/init/template/extensibility/index.js +14 -9
  30. package/lib/init/template/hana/index.js +51 -57
  31. package/lib/init/template/helm/index.js +27 -59
  32. package/lib/init/template/helm/subchart/templates/_helpers.tpl +38 -0
  33. package/lib/init/template/helm/subchart/templates/deployment.yaml +12 -12
  34. package/lib/init/template/helm/subchart/values.md +565 -194
  35. package/lib/init/template/helm/subchart/values.schema.json +163 -8
  36. package/lib/init/template/helm/subchart/values.yaml +17 -1
  37. package/lib/init/template/html5-repo/index.js +15 -11
  38. package/lib/init/template/java/index.js +15 -11
  39. package/lib/init/template/kibana-logging/index.js +30 -31
  40. package/lib/init/template/lint/index.js +17 -18
  41. package/lib/init/template/mta/index.js +18 -40
  42. package/lib/init/template/mtx/index.js +2 -3
  43. package/lib/init/template/multitenancy/index.js +27 -20
  44. package/lib/init/template/nodejs/index.js +18 -20
  45. package/lib/init/template/notebook/index.js +5 -434
  46. package/lib/init/template/pipeline/index.js +10 -10
  47. package/lib/init/template/samples/index.js +7 -16
  48. package/lib/init/template/templateBase.js +17 -18
  49. package/lib/init/template/toggles/files/cdsrc.json +5 -0
  50. package/lib/init/template/toggles/files/cdsrc.json.hbs +7 -0
  51. package/lib/init/template/toggles/index.js +12 -6
  52. package/lib/init/template/xsuaa/index.js +44 -41
  53. package/lib/init/types.d.ts +0 -59
  54. package/lib/init/util/commandUtil.js +6 -7
  55. package/lib/init/util/fsUtil.js +23 -109
  56. package/lib/init/util/merge.js +319 -0
  57. package/lib/init/util/mvnArchetypeUtil.js +6 -5
  58. package/lib/init/util/projectReader.js +125 -300
  59. package/lib/init/util/spinner.js +10 -8
  60. package/lib/init/util/templateUtil.js +25 -368
  61. package/lib/lint/Linter.js +2 -3
  62. package/lib/lint/checks.js +0 -1
  63. package/lib/lint/io.js +18 -34
  64. package/npm-shrinkwrap.json +102 -239
  65. package/package.json +3 -3
  66. package/lib/init/template/notebook/cap_magic.py +0 -118
  67. package/lib/init/template/notebook/files/{{{name}}}.ipynb.hbs +0 -90
  68. package/lib/init/template/notebook/files/{{{name}}}.json +0 -102
  69. package/lib/init/template/notebook/notebook.js +0 -394
  70. package/lib/init/util/logger.js +0 -42
@@ -376,6 +376,7 @@ function _getServiceEntityProperty(
376
376
  isKey,
377
377
  documentation,
378
378
  allowedNamespaceAttributes = -1,
379
+ nullable,
379
380
  parserContext
380
381
  ) {
381
382
  let isCollection = -1;
@@ -482,6 +483,12 @@ function _getServiceEntityProperty(
482
483
  propertyJson = propertyJson + ',\n"scale":' + 0;
483
484
  }
484
485
  }
486
+ if (nullable == "false") {
487
+ propertyJson = propertyJson + ',\n"notNull": true';
488
+ }
489
+ else if(nullable=="true" || !nullable){
490
+ propertyJson = propertyJson + ',\n"notNull": false';
491
+ }
485
492
  propertyJson = propertyJson + '\n}'
486
493
  }
487
494
  else{
@@ -521,6 +528,15 @@ function _getServiceEntityProperty(
521
528
  propertyJson += _generateNamespaceAttributes(allowedNamespaceAttributes, true);
522
529
  }
523
530
 
531
+ if(isCollection == -1) {
532
+ if (nullable === "false") {
533
+ propertyJson = propertyJson + ',\n"notNull": true';
534
+ }
535
+ else if(nullable=="true" || !nullable){
536
+ propertyJson = propertyJson + ',\n"notNull": false';
537
+ }
538
+ }
539
+
524
540
  if (propertyName)
525
541
  propertyJson = propertyJson + "\n}";
526
542
  return propertyJson;
@@ -531,6 +547,7 @@ function _getServiceComplexType(complexTypeKey, complexType, parserContext) {
531
547
  let complexTypeProperty;
532
548
  let i;
533
549
  complexTypeCSN = complexTypeCSN + '"kind": "type",\n';
550
+ complexTypeCSN = complexTypeCSN + '"@cds.external": true,\n';
534
551
  if (parserContext.allComplexTypeNamespaces[complexTypeKey]) {
535
552
  complexTypeCSN += _generateNamespaceAttributes(parserContext.allComplexTypeNamespaces[complexTypeKey], false);
536
553
  }
@@ -558,6 +575,7 @@ function _getServiceComplexType(complexTypeKey, complexType, parserContext) {
558
575
  false,
559
576
  complexTypeProperty.doc,
560
577
  complexTypePropertyNamespace,
578
+ complexTypeProperty.Nullable,
561
579
  parserContext
562
580
  );
563
581
  complexTypeCSN = complexTypeCSN + complexProperty;
@@ -587,6 +605,7 @@ function _getServiceComplexType(complexTypeKey, complexType, parserContext) {
587
605
  false,
588
606
  complexTypeProperty.doc,
589
607
  complexTypePropertyNamespace,
608
+ complexTypeProperty.Nullable,
590
609
  parserContext
591
610
  );
592
611
  }
@@ -643,6 +662,7 @@ function _parseParameter(parameter, parserContext) {
643
662
  false,
644
663
  doc,
645
664
  parameterNamespaceAttributes,
665
+ parameter["_attributes"].Nullable,
646
666
  parserContext
647
667
  );
648
668
  return csn;
@@ -692,6 +712,7 @@ function _getFunctionImport(functionImport, isBounded, entityKeysList, parserCon
692
712
  let csn = "";
693
713
  csn = csn + '"' + functionImport[0] + '": { \n';
694
714
  csn = csn + '"kind": "';
715
+
695
716
  if (functionImport[1] === "GET") {
696
717
  csn = csn + "function";
697
718
  } else if (functionImport[1] === "POST") {
@@ -703,6 +724,8 @@ function _getFunctionImport(functionImport, isBounded, entityKeysList, parserCon
703
724
  return "";
704
725
  }
705
726
  csn = csn + '"';
727
+ if (!isBounded) csn = csn + ',\n"@cds.external": true';
728
+
706
729
  if (functionImport[3] !== -1) {
707
730
  if (isBounded === 0 || (isBounded === 1 && functionImport[3] instanceof Array)) {
708
731
  let parametersCsn = _parseParametersFunctionImport(functionImport[3], entityKeysList, parserContext);
@@ -716,7 +739,7 @@ function _getFunctionImport(functionImport, isBounded, entityKeysList, parserCon
716
739
  }
717
740
  if (functionImport[2] !== -1) {
718
741
  let returnCsn = _getServiceEntityProperty(noValue, functionImport[2], noValue, noValue, noValue,
719
- noValue, noValue, noValue, -1, parserContext);
742
+ noValue, noValue, noValue, -1, noValue, parserContext);
720
743
  if (returnCsn != "") {
721
744
  csn = csn + ", \n";
722
745
  csn = csn + '"returns": { \n';
@@ -826,6 +849,12 @@ function _getPropertyAttributes(propAttributes, parserContext) {
826
849
  propOthers.push(-1);
827
850
  }
828
851
 
852
+ if (propAttributes.Nullable) {
853
+ propOthers.push(propAttributes.Nullable);
854
+ } else {
855
+ propOthers.push("true");
856
+ }
857
+
829
858
  return propOthers;
830
859
  }
831
860
 
@@ -883,6 +912,9 @@ function _generateCSNEntityKeys(entityKeysList, entityPropertiesMap, parserConte
883
912
 
884
913
  for (let i = 0; i < entityKeysList.length; i++) {
885
914
  propAttributes = entityPropertiesMap[entityKeysList[i]];
915
+ if (propAttributes[7] == "true") {
916
+ console.log(warn("Expected key element to be not nullable"));
917
+ }
886
918
  let keyCsn =
887
919
  _getServiceEntityProperty(
888
920
  entityKeysList[i],
@@ -894,6 +926,7 @@ function _generateCSNEntityKeys(entityKeysList, entityPropertiesMap, parserConte
894
926
  true,
895
927
  propAttributes[5],
896
928
  propAttributes[6],
929
+ "false",
897
930
  parserContext
898
931
  );
899
932
  csnEntity = csnEntity + keyCsn;
@@ -935,6 +968,7 @@ function _generateCSNEntityProperties(entityKeysList, entityPropertiesMap, parse
935
968
  false,
936
969
  propAttributes[5],
937
970
  propAttributes[6],
971
+ propAttributes[7],
938
972
  parserContext
939
973
  );
940
974
  csnEntity = csnEntity + propertyString;
@@ -1357,9 +1391,11 @@ function _constructServiceEntity(
1357
1391
  let csnProperties;
1358
1392
  let hasProperties;
1359
1393
  csnEntity = csnEntity + '"kind": "entity",\n';
1394
+ csnEntity = csnEntity + '"@cds.external": true,\n';
1360
1395
  if (ignorePersistenceSkip === false) {
1361
1396
  csnEntity = csnEntity + '"@cds.persistence.skip": true,\n';
1362
1397
  }
1398
+
1363
1399
  if (entityAttributes.Abstract && entityAttributes.Abstract.toUpperCase() === "TRUE") {
1364
1400
  csnEntity = csnEntity + '"abstract": true,\n';
1365
1401
  }
@@ -160,6 +160,13 @@ function generatePropertyCsn(propertyType, isPrimaryKey) {
160
160
  // primary key cannot be of type Collection
161
161
  if (propertyType.$Collection)
162
162
  throw new Error(messages.COLLECTION_IN_KEY);
163
+ if (propertyType.$Nullable === true) {
164
+ console.log(warn("Expected key element to be not nullable"));
165
+ }
166
+ typeProperties["notNull"] = true;
167
+ }
168
+ else {
169
+ typeProperties["notNull"] = propertyType.$Nullable ? false : true;
163
170
  }
164
171
  _includeExternalNamespaceAnnotation(propertyType, property);
165
172
  // conditions have to be made
@@ -179,7 +186,7 @@ function generatePropertyCsn(propertyType, isPrimaryKey) {
179
186
  typeProperties["@odata.Precision"] = propertyType.$Precision;
180
187
  } else {
181
188
  typeProperties.type = edmxncdsdatatype[propertyType.$Type];
182
- //typeProperties["@odata.Precision"] = 0;
189
+ // typeProperties["@odata.Precision"] = 0;
183
190
  }
184
191
  } else if (propertyType.$Precision && !_isValidDataType(propertyType.$Type)) {
185
192
  typeProperties.type = edmxncdsdatatype[propertyType.$Type + '_p'];
@@ -329,6 +336,7 @@ function _generateCSNForEntityType(ignorePersistenceSkip, mockServerUc, parserCo
329
336
  if (key) {
330
337
  entityCsn[key] = {};
331
338
  entityCsn[key].kind = 'entity';
339
+ entityCsn[key]['@cds.external'] = true;
332
340
  if (!ignorePersistenceSkip) {
333
341
  entityCsn[key]['@cds.persistence.skip'] = true;
334
342
  }
@@ -465,10 +473,10 @@ function _parseEntityType(schemaDataList, ignorePersistenceSkip, mockServerUc, p
465
473
  function _parseEntityContainer(entityCSN, schemaData, parserContext) {
466
474
  Object.entries(schemaData[0][parserContext.jsonEntityContainerName]).forEach(entry => {
467
475
  if (entityCSN[parserContext.namespace + '.' + entry[0]])
468
- //Captured the annotations at entity set and entity type name level
476
+ // Captured the annotations at entity set and entity type name level
469
477
  _includeExternalNamespaceAnnotation(entry[1], entityCSN[parserContext.namespace + '.' + entry[0]]);
470
478
  if (entry[0].startsWith('@')) {
471
- //Captured the annotations at entity container name level
479
+ // Captured the annotations at entity container name level
472
480
  entityCSN[parserContext.namespace][entry[0]] = entry[1];
473
481
  }
474
482
  });
@@ -504,6 +512,8 @@ function _generateCSNForEnumType(schemaData, parserContext) {
504
512
  eTypes = _collectEnumType(schemaData, parserContext);
505
513
  Object.keys(eTypes).forEach(element => {
506
514
  enumCsn[element] = {};
515
+ enumCsn[element].kind = 'type';
516
+ enumCsn[element]['@cds.external'] = true;
507
517
  enumCsn[element].enum = {};
508
518
  enumCsn[element].type = eTypes[element].$Type != null ? edmxncdsdatatype[eTypes[element].$Type] : 'cds.LargeString';
509
519
  Object.keys(eTypes[element]).forEach(property => {
@@ -585,15 +595,15 @@ function _collectBounded(schemaDataList, flag, parserContext) {
585
595
  function _getDatatype(datatype, parserContext) {
586
596
  let type = undefined;
587
597
  if (datatype === undefined) {
588
- type = "cds.LargeString"; //intentionally used LargeString
598
+ type = "cds.LargeString"; // intentionally used LargeString
589
599
  } else if (parserContext.entitySetToEntityTypeMap.get(datatype) && parserContext.entitySetToEntityTypeMap.get(datatype)[0]) {
590
- //mapping to entity set if type is entity type
600
+ // mapping to entity set if type is entity type
591
601
  type = parserContext.namespace + "." + parserContext.entitySetToEntityTypeMap.get(datatype)[0];
592
602
  } else if (parserContext.complexTypes[datatype] || parserContext.typeDefinitions[datatype] || parserContext.enumTypes[datatype]) {
593
- //if type is complex type, type definition or an enum type
603
+ // if type is complex type, type definition or an enum type
594
604
  type = datatype;
595
605
  } else {
596
- //checking if type is an entity set
606
+ // checking if type is an entity set
597
607
  for (const element of parserContext.entitySetToEntityTypeMap.keys()) {
598
608
  if (parserContext.namespace + "." + parserContext.entitySetToEntityTypeMap.get(element) === datatype)
599
609
  type = datatype;
@@ -604,7 +614,7 @@ function _getDatatype(datatype, parserContext) {
604
614
  })
605
615
  }
606
616
 
607
- //will return undefined if type is not supported
617
+ // will return undefined if type is not supported
608
618
  return type;
609
619
  }
610
620
 
@@ -654,7 +664,7 @@ function _parseBounded(csnDefs, flag, parserContext) {
654
664
  let paramType = {};
655
665
  let annotations = {};
656
666
  _includeExternalNamespaceAnnotation(paramObj, annotations);
657
- //check if the parameter type is pre-defined, undefined or custom defined
667
+ // check if the parameter type is pre-defined, undefined or custom defined
658
668
  if (edmxncdsdatatype[paramObj.$Type] || edmxncdsdatatype[paramObj.$Type + "_a"])
659
669
  paramType = generatePropertyCsn(paramObj, false);
660
670
  else {
@@ -667,8 +677,14 @@ function _parseBounded(csnDefs, flag, parserContext) {
667
677
  if (paramObj.$Collection && !paramType.items) {
668
678
  csnDefs[boundedEntityName].actions[name].params[paramName] = {};
669
679
  csnDefs[boundedEntityName].actions[name].params[paramName].items = paramType;
670
- } else
680
+ csnDefs[boundedEntityName].actions[name].params[paramName].items["notNull"] = paramObj?.$Nullable ? false : true;
681
+
682
+ } else {
671
683
  csnDefs[boundedEntityName].actions[name].params[paramName] = paramType;
684
+ if (!paramType.items) {
685
+ csnDefs[boundedEntityName].actions[name].params[paramName].notNull = paramObj?.$Nullable ? false : true;
686
+ }
687
+ }
672
688
  }
673
689
  }
674
690
  else {
@@ -680,7 +696,7 @@ function _parseBounded(csnDefs, flag, parserContext) {
680
696
  }
681
697
  }
682
698
  }
683
- //if parameters has no entries
699
+ // if parameters has no entries
684
700
  if (csnDefs[boundedEntityName].actions[name].params && Object.keys(csnDefs[boundedEntityName].actions[name].params).length === 0) {
685
701
  delete csnDefs[boundedEntityName].actions[name].params;
686
702
  }
@@ -700,10 +716,16 @@ function _parseBounded(csnDefs, flag, parserContext) {
700
716
  if (returnType.type || returnType.items.type) {
701
717
  csnDefs[boundedEntityName].actions[name].returns = {};
702
718
  // check if return type is a collection
703
- if (obj[j].$ReturnType.$Collection && !returnType.items)
719
+ if (obj[j].$ReturnType.$Collection && !returnType.items) {
704
720
  csnDefs[boundedEntityName].actions[name].returns.items = returnType;
705
- else
721
+ csnDefs[boundedEntityName].actions[name].returns.items["notNull"] = obj[j].$ReturnType?.$Nullable ? false : true
722
+ }
723
+ else {
706
724
  csnDefs[boundedEntityName].actions[name].returns = returnType;
725
+ if (!returnType.items) {
726
+ csnDefs[boundedEntityName].actions[name].returns["notNull"] = obj[j].$ReturnType?.$Nullable ? false : true
727
+ }
728
+ }
707
729
  }
708
730
  } else {
709
731
  let message = '"' + obj[j].$ReturnType.$Type + '" is not supported (in return type)';
@@ -752,6 +774,7 @@ function _generateCSNForComplexType(schemaData, parserContext) {
752
774
  Object.keys(cTypes).forEach(element => {
753
775
  complexCsn[element] = {};
754
776
  complexCsn[element].kind = 'type';
777
+ complexCsn[element]['@cds.external'] = true;
755
778
  complexCsn[element].elements = {};
756
779
  // inheritance handling
757
780
  baseType = cTypes[element].$BaseType;
@@ -791,6 +814,7 @@ function _parseTypeDefinition(parserContext) {
791
814
  Object.keys(parserContext.typeDefinitions).forEach(element => {
792
815
  typeDef[element] = {};
793
816
  typeDef[element].kind = 'type';
817
+ typeDef[element]['@cds.external'] = true;
794
818
  if (!parserContext.typeDefinitions[element].$Type ||
795
819
  edmxncdsdatatype[parserContext.typeDefinitions[element].$Type]
796
820
  ) {
@@ -824,6 +848,7 @@ function _parseUnbounded(schemaData, flag, parserContext) {
824
848
  objData = schemaData[0][temp][0];
825
849
  obj[objType] = {};
826
850
  obj[objType].kind = unboundedCsnKind;
851
+ obj[objType]['@cds.external'] = true;
827
852
  _includeExternalNamespaceAnnotation(objData, obj[objType]);
828
853
  // add params
829
854
  if (objData.$Parameter && objData.$Parameter.length > 0) {
@@ -845,8 +870,13 @@ function _parseUnbounded(schemaData, flag, parserContext) {
845
870
  if (objData.$Parameter[i].$Collection && !paramType.items) {
846
871
  obj[objType].params[objData.$Parameter[i].$Name] = {};
847
872
  obj[objType].params[objData.$Parameter[i].$Name].items = paramType;
848
- } else
873
+ obj[objType].params[objData.$Parameter[i].$Name].items["notNull"] = objData.$Parameter[i]?.$Nullable ? false : true;
874
+ } else {
849
875
  obj[objType].params[objData.$Parameter[i].$Name] = paramType;
876
+ if (!paramType.items) {
877
+ obj[objType].params[objData.$Parameter[i].$Name]["notNull"] = objData.$Parameter[i]?.$Nullable ? false : true;
878
+ }
879
+ }
850
880
  }
851
881
  } else {
852
882
  let message = '"' + objData.$Parameter[i].$Type + '" is not supported (in element:"' + temp + '")';
@@ -856,7 +886,7 @@ function _parseUnbounded(schemaData, flag, parserContext) {
856
886
  Object.assign(obj[objType].params[objData.$Parameter[i].$Name], annotations)
857
887
  }
858
888
  }
859
- //if parameters has no entries
889
+ // if parameters has no entries
860
890
  if (obj[objType].params && Object.keys(obj[objType].params).length === 0) {
861
891
  delete obj[objType].params;
862
892
  }
@@ -879,8 +909,13 @@ function _parseUnbounded(schemaData, flag, parserContext) {
879
909
  if (objData.$ReturnType.$Collection && !returnValue.items) {
880
910
  obj[objType].returns.items = {};
881
911
  obj[objType].returns.items = returnValue;
882
- } else
912
+ obj[objType].returns.items["notNull"] = objData.$ReturnType?.$Nullable ? false : true;
913
+ } else {
883
914
  obj[objType].returns = returnValue;
915
+ if (!returnValue.items) {
916
+ obj[objType].returns["notNull"] = objData.$ReturnType?.$Nullable ? false : true;
917
+ }
918
+ }
884
919
  }
885
920
  }
886
921
  else {
@@ -994,9 +1029,9 @@ function _checkAnnotatationTerm(annotation, path, no_of_terms, targetString, voc
994
1029
  }
995
1030
  }
996
1031
 
997
- function checkEntitySetMap(pathName, parserContext) {
1032
+ function checkEntitySetMap(pathName, parserContext, index = 0) {
998
1033
  if (parserContext.entitySetToEntityTypeMap.get(pathName) != null) {
999
- pathName = parserContext.namespace + '.' + parserContext.entitySetToEntityTypeMap.get(pathName)[0];
1034
+ pathName = parserContext.namespace + '.' + parserContext.entitySetToEntityTypeMap.get(pathName)[index];
1000
1035
  }
1001
1036
  return pathName;
1002
1037
  }
@@ -1004,7 +1039,21 @@ function checkEntitySetMap(pathName, parserContext) {
1004
1039
  function _checkAnnotationTarget(annotation, cdsDefs, str, no_of_terms, vocab, parserContext) {
1005
1040
  if ((annotation[0].indexOf('/') === -1 && annotation[0].indexOf('(') === -1) || annotation[0].includes("Container")) {
1006
1041
  if (cdsDefs[annotation[0]]) {
1007
- _checkAnnotatationTerm(annotation, cdsDefs[annotation[0]], no_of_terms, str, vocab);
1042
+ let path = annotation[0].split('/');
1043
+ let pathFromEntityTypeMap = parserContext.entitySetToEntityTypeMap.get(path[0]);
1044
+ if (pathFromEntityTypeMap != null) {
1045
+ if (pathFromEntityTypeMap.length > 1) {
1046
+ for (let index = 0; index < pathFromEntityTypeMap.length; index++) {
1047
+ let path1 = checkEntitySetMap(path[0], parserContext, index);
1048
+ _checkAnnotatationTerm(annotation, cdsDefs[path1], no_of_terms, str, vocab);
1049
+ }
1050
+ } else {
1051
+ _checkAnnotatationTerm(annotation, cdsDefs[annotation[0]], no_of_terms, str, vocab);
1052
+ }
1053
+ }
1054
+ else {
1055
+ _checkAnnotatationTerm(annotation, cdsDefs[annotation[0]], no_of_terms, str, vocab);
1056
+ }
1008
1057
  }
1009
1058
  if (annotation[0].indexOf('/') > 0) {
1010
1059
  let path = annotation[0].split('/');
@@ -1019,14 +1068,43 @@ function _checkAnnotationTarget(annotation, cdsDefs, str, no_of_terms, vocab, pa
1019
1068
  let actualPath = checkEntitySetMap(path, parserContext);
1020
1069
  _checkAnnotatationTerm(annotation, cdsDefs[actualPath], no_of_terms, str, vocab);
1021
1070
  }
1071
+ else if (annotation[0].indexOf('(') === -1 && (annotation[0].indexOf('/') === -1)) {
1072
+ let path = annotation[0].split('/');
1073
+ let pathFromEntityTypeMap = parserContext.entitySetToEntityTypeMap.get(path[0]);
1074
+ if (pathFromEntityTypeMap != null) {
1075
+ if (pathFromEntityTypeMap.length > 1) {
1076
+ for (let index = 0; index < pathFromEntityTypeMap.length; index++) {
1077
+ let path1 = checkEntitySetMap(path[0], parserContext, index);
1078
+ _checkAnnotatationTerm(annotation, cdsDefs[path1], no_of_terms, str, vocab);
1079
+ }
1080
+ }
1081
+ }
1082
+ }
1022
1083
  }
1023
1084
  else if (annotation[0].indexOf('(') === -1 && !(annotation[0].indexOf('/') === -1)) {
1024
1085
  let path = annotation[0].split('/');
1025
- let path1 = checkEntitySetMap(path[0], parserContext);
1026
- if (cdsDefs[path1]) {
1027
- _checkAnnotatationTerm(annotation, cdsDefs[path1]["elements"][path[1]], no_of_terms, str, vocab);
1086
+ let pathFromEntityTypeMap = parserContext.entitySetToEntityTypeMap.get(path[0]);
1087
+ if (pathFromEntityTypeMap != null) {
1088
+ if (pathFromEntityTypeMap.length > 1) {
1089
+ for (let index = 0; index < pathFromEntityTypeMap.length; index++) {
1090
+ let path1 = checkEntitySetMap(path[0], parserContext, index);
1091
+ _checkAnnotatationTerm(annotation, cdsDefs[path1]["elements"][path[1]], no_of_terms, str, vocab);
1092
+ }
1093
+ }
1094
+ else {
1095
+ let path1 = checkEntitySetMap(path[0], parserContext);
1096
+ if (cdsDefs[path1]) {
1097
+ _checkAnnotatationTerm(annotation, cdsDefs[path1]["elements"][path[1]], no_of_terms, str, vocab);
1098
+ }
1099
+ }
1028
1100
  }
1029
- } else {
1101
+ else {
1102
+ if (cdsDefs[path[0]]) {
1103
+ _checkAnnotatationTerm(annotation, cdsDefs[path[0]]["elements"][path[1]], no_of_terms, str, vocab);
1104
+ }
1105
+ }
1106
+ }
1107
+ else {
1030
1108
  let path = annotation[0].split('(');
1031
1109
  let actualPath = checkEntitySetMap(path[0], parserContext);
1032
1110
  if (cdsDefs[actualPath] === undefined) {
@@ -1,6 +1,6 @@
1
1
  const os = require('os');
2
2
 
3
- const MAVEN_ARCHETYPE_VERSION = '1.28.0';
3
+ const MAVEN_ARCHETYPE_VERSION = '1.28.1';
4
4
 
5
5
  const constants = {
6
6
  IS_WIN: (os.platform() === 'win32'),
package/lib/init/index.js CHANGED
@@ -1,7 +1,5 @@
1
1
  const path = require('path');
2
2
 
3
- const { defaultLogger } = require('./util/logger');
4
- const FsUtil = require('./util/fsUtil');
5
3
  const term = require('../util/term');
6
4
  const Spinner = require('./util/spinner');
7
5
 
@@ -11,11 +9,12 @@ const { OPTIONS_PRIORITY, COMMAND_ADD, COMMAND_INIT,
11
9
  OPTION_NODEJS, OPTION_JAVA, OPTION_HELM,
12
10
  OPTION_PIPELINE, OPTION_SAMPLES, OPTION_CF_MANIFEST, PROJECT_FILES, REGEX_PROJECT_NAME } = require('./constants');
13
11
 
14
- module.exports = class CDSGenerator {
15
- constructor(fsUtil, logger) {
16
- this.fsUtil = fsUtil || new FsUtil();
17
- this.logger = logger || defaultLogger;
12
+ const cds = require('../cds'), { exists, readdir } = cds.utils
13
+ const LOG = console
14
+ const DEBUG = /\bcli\b/.test(process.env.DEBUG) && console.debug
18
15
 
16
+ module.exports = class CDSGenerator {
17
+ constructor() {
19
18
  this.cwd = process.cwd();
20
19
 
21
20
  this.uiConfig = [
@@ -163,7 +162,7 @@ module.exports = class CDSGenerator {
163
162
 
164
163
  async _findProjectFile(projectPath) {
165
164
  for (const file of PROJECT_FILES) {
166
- if (await this.fsUtil.pathExists(path.join(projectPath, file))) {
165
+ if (exists(path.join(projectPath, file))) {
167
166
  return file;
168
167
  }
169
168
  }
@@ -174,7 +173,7 @@ module.exports = class CDSGenerator {
174
173
  _initialize(projectName, options = {}) {
175
174
  // deprecated, only for compatibility
176
175
  if (options.verbose) {
177
- this.logger.warn(`Parameter 'verbose' is no longer supported. Use environment variable 'DEBUG=true' to obtain detailed output.`);
176
+ LOG.warn(`Parameter 'verbose' is no longer supported. Use environment variable 'DEBUG=true' to obtain detailed output.`);
178
177
  }
179
178
 
180
179
  this.cwd = options.cwd || process.cwd();
@@ -190,47 +189,42 @@ module.exports = class CDSGenerator {
190
189
  case COMMAND_INIT: {
191
190
  const relativeProjectPath = path.relative(this.cwd, this.projectPath);
192
191
  const folderName = (relativeProjectPath ? `.${path.sep}${relativeProjectPath}` : 'current folder');
193
- this.logger.log(`Creating new cap project in ${folderName}`);
192
+ LOG.info(`Creating new cap project in ${folderName}`);
194
193
  break;
195
194
  }
196
-
197
195
  case COMMAND_ADD:
198
- this.logger.log(`Adding feature(s) to project in current folder`);
196
+ LOG.info(`Adding feature(s) to project in current folder`);
199
197
  break;
200
-
201
- default:
202
198
  }
203
199
 
204
200
  if (this.options.force) {
205
- this.logger.log(`Using '--force' ... existing files will be overwritten...!`);
201
+ LOG.info(`Using '--force' ... existing files will be overwritten...!`);
206
202
  }
207
203
 
208
- this.logger.log();
204
+ LOG.info();
209
205
  }
210
206
 
211
207
  async _process() {
212
- this.logger.debug(`Project path: ${this.projectPath}`);
208
+ DEBUG && DEBUG(`Project path: ${this.projectPath}`);
213
209
 
214
210
  await this._validateOptions();
215
211
  await this._fillTemplateList();
216
212
 
217
213
  for (const template of this.templateList) {
218
214
  const msg = `Adding feature '${template.name}'...`;
219
- if (template.dontAnnounce) {
220
- await template.run();
221
- } else if (this.logger.isDebug) {
222
- this.logger.log(msg);
215
+ if (DEBUG) {
216
+ LOG.info(msg);
223
217
  await template.run();
224
218
  } else {
225
- const spinner = new Spinner(this.logger);
219
+ const spinner = new Spinner();
226
220
  await spinner.run(msg, async () => { // NOSONAR
227
221
  return template.run();
228
222
  });
229
223
  }
230
224
  }
231
225
 
232
- this.logger.log(`Done adding features`);
233
- this.logger.log();
226
+ LOG.info(`Done adding features`);
227
+ LOG.info();
234
228
  }
235
229
 
236
230
  async _createTemplate(filename) {
@@ -239,7 +233,7 @@ module.exports = class CDSGenerator {
239
233
  return new TemplateClass(this.projectPath, this);
240
234
  } catch (err) {
241
235
  if (err.code === 'MODULE_NOT_FOUND') {
242
- const entries = (await this.fsUtil.readdir(path.join(__dirname, 'template')))
236
+ const entries = (await readdir(path.join(__dirname, 'template')))
243
237
  .filter(entry =>
244
238
  !entry.startsWith('_') &&
245
239
  !entry.endsWith('.js') &&
@@ -261,8 +255,8 @@ module.exports = class CDSGenerator {
261
255
  if (!templates.has(option)) {
262
256
  const template = await this._createTemplate(option);
263
257
 
264
- if (await template.checkEnabled()) {
265
- this.logger.debug(`Adding feature '${template.name}'`);
258
+ if (await template.canRun()) {
259
+ DEBUG && DEBUG(`Adding feature '${template.name}'`);
266
260
 
267
261
  templates.set(option, template);
268
262
  const deps = await template.getDependencies();
@@ -278,30 +272,14 @@ module.exports = class CDSGenerator {
278
272
  }).map((entry) => entry[1]);
279
273
 
280
274
  // check debug to avoid lengthy computation when not in debug mode
281
- this.logger.isDebug && this.logger.debug(`Features: ${this.templateList.map((obj) => {
282
- return obj.name;
283
- }).join(', ')}`);
275
+ DEBUG && DEBUG(`Features: ${this.templateList.map(({name}) => name).join(', ')}`);
284
276
  }
285
277
 
286
278
  async stepEnd() {
287
- this.logger.isDebug && this._showFiles();
288
-
289
279
  for (const template of this.templateList) {
290
280
  await template.finalize();
291
281
  }
292
-
293
- this.logger.log();
294
- }
295
-
296
- _showFiles() {
297
- const files = this.fsUtil.getTouchedFiles();
298
- if (files && files.length > 0) {
299
- this.logger.log(`Added / changed files`);
300
- for (const file of files) {
301
- this.logger.log(file);
302
- }
303
- this.logger.log();
304
- }
282
+ LOG.info();
305
283
  }
306
284
 
307
285
  _cleanupOptions() {
@@ -347,7 +325,7 @@ module.exports = class CDSGenerator {
347
325
  const keySplit = key.split(/:/);
348
326
  if (keySplit.length === 2) {
349
327
  if (!this.options.add.has(keySplit[0])) {
350
- this.logger.warn(`ignoring option ${key} since ${keySplit[0]} is not part of specified feature list: ${Array.from(this.options.add).join(', ')}`);
328
+ LOG.warn(`ignoring option ${key} since ${keySplit[0]} is not part of specified feature list: ${Array.from(this.options.add).join(', ')}`);
351
329
  }
352
330
  }
353
331
  }