@sap/cds-dk 4.6.3 → 4.7.3

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.
@@ -22,6 +22,7 @@ let allowAllNamespaces = false;
22
22
  let messages = require("./message").getMessages();
23
23
  let common = require("./common");
24
24
  let versionInfo = require('../../package.json').version;
25
+ const { warn } = require('@sap/cds/bin/utils/term');
25
26
 
26
27
  let edmxncdsdatatype = {
27
28
  "Edm.String": "cds.LargeString",
@@ -30,15 +31,14 @@ let edmxncdsdatatype = {
30
31
  "Edm.Int32": "cds.Integer",
31
32
  "Edm.Int64": "cds.Integer64",
32
33
  "Edm.Decimal": "cds.DecimalFloat",
33
- "Edm.DateTime": "cds.DateTime",
34
- "Edm.DateTimeOffset": "cds.Timestamp",
34
+ "Edm.DateTime": "cds.DateTime",
35
+ "Edm.DateTimeOffset": "cds.DateTime",
35
36
  "Edm.Time": "cds.Time",
36
37
  "Edm.Binary": "cds.LargeBinary",
37
38
  "Edm.Guid": "cds.UUID",
38
39
  "Edm.Byte": "cds.Integer",
39
40
  "Edm.SByte": "cds.Integer",
40
41
  "Edm.Double": "cds.Double",
41
- "Edm.Single": "cds.DecimalFloat",
42
42
  // Special handling of data types
43
43
  "Edm.String_m": "cds.String", // Max length
44
44
  "Edm.Decimal_p": "cds.Decimal", // Precision, scale
@@ -47,6 +47,11 @@ let edmxncdsdatatype = {
47
47
  "Edm.Binary_m": "cds.Binary", // Max Length
48
48
  "Edm.Byte_m": "cds.Integer", // Max Length
49
49
  "Edm.Double_p": "cds.Double", // Precision, scale
50
+ // Special handling with annotations
51
+ "Edm.Single_a": "cds.Double",
52
+ "Edm.Stream_a" : "cds.LargeBinary",
53
+ "Edm.DateTimeOffset_a" : "cds.Timestamp", //precision > 0
54
+ "Edm.DateTime_a" : "cds.Timestamp" //precision > 0
50
55
  };
51
56
 
52
57
  function _initialize() {
@@ -420,8 +425,9 @@ function _getServiceEntityProperty(
420
425
  } else if (precision && precision > 0) {
421
426
  cdsDataType = edmxncdsdatatype[dataType + "_p"];
422
427
  // Falling back to actual data type as precision has no meaning for 'Date' related data types
428
+ // Using _a data type if precision is there for 'Date' related data types
423
429
  if (cdsDataType === undefined) {
424
- cdsDataType = edmxncdsdatatype[dataType];
430
+ cdsDataType = edmxncdsdatatype[dataType + "_a"];
425
431
  hasInvalidPrecision = true;
426
432
  }
427
433
  } else if (displayFormat && displayFormat === "Date") {
@@ -430,6 +436,10 @@ function _getServiceEntityProperty(
430
436
  cdsDataType = edmxncdsdatatype[dataType];
431
437
  }
432
438
 
439
+ //checks if it's an annotation case
440
+ if (!cdsDataType) {
441
+ cdsDataType = edmxncdsdatatype[dataType + "_a"];
442
+ }
433
443
  // Lookup from complex type properties
434
444
  if (!cdsDataType && allComplexTypes[dataType]) {
435
445
  cdsDataType = dataType;
@@ -447,6 +457,18 @@ function _getServiceEntityProperty(
447
457
  cdsDataType = dataType;
448
458
  }
449
459
 
460
+ //if the cdsDataType is undefined/ not supported
461
+ if(cdsDataType === undefined)
462
+ {
463
+ let message = '"' + dataType + '" is not supported';
464
+ if(propertyName)
465
+ message += ' (in element:"' + propertyName + '")';
466
+ else
467
+ message += ' (in return type)'
468
+ console.log(warn(message));
469
+ return "";
470
+ }
471
+
450
472
  if(propertyName)
451
473
  propertyJson = '"' + propertyName + '": {\n';
452
474
 
@@ -458,6 +480,13 @@ function _getServiceEntityProperty(
458
480
  propertyJson = propertyJson + '"items": { \n'
459
481
  }
460
482
  propertyJson = propertyJson + '"type":"' + cdsDataType + '"';
483
+
484
+ //if annotations to be added
485
+ if(edmxncdsdatatype[dataType + "_a"] && cdsDataType != "cds.Date")
486
+ {
487
+ propertyJson = propertyJson + ',\n"@odata.type": "' + dataType + '"';
488
+ }
489
+
461
490
  if (length && length > 0) {
462
491
  propertyJson = propertyJson + ',\n"length":' + length;
463
492
  } else if (precision && precision > 0 && hasInvalidPrecision === false) {
@@ -468,6 +497,14 @@ function _getServiceEntityProperty(
468
497
  propertyJson = propertyJson + ',\n"scale":' + 0;
469
498
  }
470
499
  }
500
+
501
+ //adding precision in case of DateTime datatypes
502
+ if((dataType === "Edm.DateTimeOffset" || dataType === "Edm.DateTime") && cdsDataType != "cds.Date")
503
+ {
504
+ if(!precision || precision === -1) precision = 0;
505
+ propertyJson = propertyJson + ',\n"@odata.precision": ' + precision;
506
+ }
507
+
471
508
  if(isCollection === 1)
472
509
  {
473
510
  propertyJson = propertyJson + '\n}'
@@ -503,12 +540,10 @@ function _getServiceComplexType(complexTypeKey, complexType) {
503
540
  complexTypeProperty = complexType[i]._attributes;
504
541
  if(complexType[i].Documentation)
505
542
  complexTypeProperty.doc = _parseDocumentationTag(complexType[i].Documentation);
506
-
507
543
  let namespaceAttributes = namespaceAttributeFilter(complexTypeProperty)
508
544
  const complexTypePropertyNamespace = namespaceAttributes.length ? namespaceAttributes : -1
509
545
 
510
- complexTypeCSN =
511
- complexTypeCSN +
546
+ let complexProperty =
512
547
  _getServiceEntityProperty(
513
548
  complexTypeProperty.Name,
514
549
  complexTypeProperty.Type,
@@ -521,7 +556,8 @@ function _getServiceComplexType(complexTypeKey, complexType) {
521
556
  -1,
522
557
  complexTypePropertyNamespace
523
558
  );
524
- if (i !== complexType.length - 1) {
559
+ complexTypeCSN = complexTypeCSN + complexProperty;
560
+ if (i !== complexType.length - 1 && complexProperty != "") {
525
561
  complexTypeCSN = complexTypeCSN + ",\n";
526
562
  } else {
527
563
  complexTypeCSN = complexTypeCSN + "\n";
@@ -551,6 +587,10 @@ function _getServiceComplexType(complexTypeKey, complexType) {
551
587
  complexTypePropertyNamespace
552
588
  );
553
589
  }
590
+
591
+ if (complexTypeCSN && (complexTypeCSN.endsWith(",\n") || complexTypeCSN.endsWith(",\n\n"))) {
592
+ complexTypeCSN = complexTypeCSN.substring(0, complexTypeCSN.lastIndexOf(",\n")) + "\n";
593
+ }
554
594
  }
555
595
  complexTypeCSN = complexTypeCSN + "}\n";
556
596
  if (allInheritedComplexTypes[complexTypeKey]) {
@@ -618,13 +658,15 @@ function _parseParameter(parameter)
618
658
 
619
659
  function _parseParametersFunctionImport(parameters, isBounded) {
620
660
  let csn = "";
661
+ let parameterCsn = "";
621
662
  let i = isBounded===1 ? 1 : 0;
622
663
  if(parameters.length)
623
664
  {
624
665
  for(i;i<parameters.length;i++)
625
666
  {
626
- csn = csn + _parseParameter(parameters[i]);
627
- if(i!== parameters.length - 1) {
667
+ parameterCsn = _parseParameter(parameters[i]);
668
+ csn = csn + parameterCsn;
669
+ if(i!== parameters.length - 1 && parameterCsn != "") {
628
670
  csn = csn + ",\n";
629
671
  } else {
630
672
  csn = csn + "\n";
@@ -634,6 +676,9 @@ function _parseParametersFunctionImport(parameters, isBounded) {
634
676
  csn = csn + _parseParameter(parameters);
635
677
  }
636
678
 
679
+ if (csn && (csn.endsWith(",\n") || csn.endsWith(",\n\n"))) {
680
+ csn= csn.substring(0, csn.lastIndexOf(",\n")) + "\n";
681
+ }
637
682
  return csn;
638
683
  }
639
684
 
@@ -654,25 +699,33 @@ function _getFunctionImport(functionImport,isBounded) {
654
699
  {
655
700
  if(isBounded === 0 || (isBounded === 1 && functionImport[3] instanceof Array ))
656
701
  {
657
- csn = csn + ", \n";
658
- csn = csn + '"params": { \n';
659
- csn = csn + _parseParametersFunctionImport(functionImport[3],isBounded);
660
- csn = csn + '\n }';
702
+ let parametersCsn = _parseParametersFunctionImport(functionImport[3],isBounded);
703
+ if(parametersCsn != "")
704
+ {
705
+ csn = csn + ", \n";
706
+ csn = csn + '"params": { \n';
707
+ csn = csn + _parseParametersFunctionImport(functionImport[3],isBounded);
708
+ csn = csn + '\n }';
709
+ }
661
710
  }
662
711
  }
663
712
  if(functionImport[2] !== -1)
664
713
  {
665
- csn = csn + ", \n";
666
- csn = csn + '"returns": { \n';
667
714
  let isCollection = -1;
668
715
  if(functionImport[2].substring(0,10) === 'Collection')
669
716
  {
670
717
  functionImport[2] = functionImport[2].substring(11,functionImport[2].length-1);
671
718
  isCollection = 1;
672
719
  }
673
- //return type
674
- csn = csn + _getServiceEntityProperty(noValue,functionImport[2],noValue,noValue,noValue,noValue,noValue,noValue,isCollection);
675
- csn = csn + '\n }';
720
+ let returnCsn = _getServiceEntityProperty(noValue,functionImport[2],noValue,noValue,noValue,noValue,noValue,noValue,isCollection);
721
+ if(returnCsn != "")
722
+ {
723
+ csn = csn + ", \n";
724
+ csn = csn + '"returns": { \n';
725
+ //return type
726
+ csn = csn + _getServiceEntityProperty(noValue,functionImport[2],noValue,noValue,noValue,noValue,noValue,noValue,isCollection);
727
+ csn = csn + '\n }';
728
+ }
676
729
  }
677
730
  if(functionImport[4] !== -1 && functionImport[4])
678
731
  {
@@ -830,8 +883,7 @@ function _generateCSNEntityKeys(entityKeysList, entityPropertiesMap) {
830
883
  let i;
831
884
  for (i = 0; i < entityKeysList.length; i++) {
832
885
  propAttributes = entityPropertiesMap[entityKeysList[i]];
833
- csnEntity =
834
- csnEntity +
886
+ let keyCsn =
835
887
  _getServiceEntityProperty(
836
888
  entityKeysList[i],
837
889
  propAttributes[0],
@@ -844,10 +896,14 @@ function _generateCSNEntityKeys(entityKeysList, entityPropertiesMap) {
844
896
  -1,
845
897
  propAttributes[6]
846
898
  );
847
- if (i !== entityKeysList.length - 1) {
899
+ csnEntity = csnEntity + keyCsn;
900
+ if (i !== entityKeysList.length - 1 && keyCsn != "") {
848
901
  csnEntity = csnEntity + ",\n";
849
902
  }
850
903
  }
904
+ if (csnEntity && (csnEntity.endsWith(",\n") || csnEntity.endsWith(",\n\n"))) {
905
+ csnEntity= csnEntity.substring(0, csnEntity.lastIndexOf(",\n")) + "\n";
906
+ }
851
907
  return csnEntity;
852
908
  }
853
909
 
@@ -869,8 +925,7 @@ function _generateCSNEntityProperties(entityKeysList, entityPropertiesMap) {
869
925
  // Include Property which are not part of keys
870
926
  if (entityKeysList.indexOf(property) === -1) {
871
927
  propAttributes = entityPropertiesMap[property];
872
- csnEntity =
873
- csnEntity +
928
+ let propertyString =
874
929
  _getServiceEntityProperty(
875
930
  property,
876
931
  propAttributes[0],
@@ -883,7 +938,8 @@ function _generateCSNEntityProperties(entityKeysList, entityPropertiesMap) {
883
938
  -1,
884
939
  propAttributes[6]
885
940
  );
886
- if (i !== entityProperties.length - 1) {
941
+ csnEntity = csnEntity + propertyString;
942
+ if (i !== entityProperties.length - 1 && propertyString != "") {
887
943
  csnEntity = csnEntity + ",\n";
888
944
  } else {
889
945
  csnEntity = csnEntity + "\n";
@@ -891,7 +947,9 @@ function _generateCSNEntityProperties(entityKeysList, entityPropertiesMap) {
891
947
  }
892
948
  }
893
949
  // Last property can be an key; eliminate additional delimiter.
894
- if (csnEntity && csnEntity.endsWith(",\n")) {
950
+ // Last property can have undefined datatype and be ignored too
951
+ //doubt
952
+ if (csnEntity && (csnEntity.endsWith(",\n") || csnEntity.endsWith(",\n\n"))) {
895
953
  csnEntity = csnEntity.substring(0, csnEntity.lastIndexOf(",\n")) + "\n";
896
954
  }
897
955
  return csnEntity;
@@ -1179,12 +1237,11 @@ function _getServiceEntityNavigationProperty(navPropAttributes, mockServerUc) {
1179
1237
  if(allowedNamespaceAttributes.length) {
1180
1238
  csn += _generateNamespaceAttributes(allowedNamespaceAttributes, false);
1181
1239
  }
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
- }
1240
+ // annotation for on conditions
1241
+ csn = csn + `"@cds.ambiguous": "missing on condition?",\n`;
1242
+ // if documentation exists for navigation property
1243
+ if (navPropDoc)
1244
+ csn = csn + '"doc":' + ` "${navPropDoc}",\n`;
1188
1245
  csn = csn + '"type": "cds.Association",\n';
1189
1246
  csn = csn +
1190
1247
  _getCSNAssociatedEntitySet(
@@ -1277,13 +1334,18 @@ function _constructServiceEntity(
1277
1334
 
1278
1335
  // Key Entity attributes
1279
1336
  csnKeys = _generateCSNEntityKeys(entityKeysList, entityPropertiesMap);
1280
- csnEntity = csnEntity + csnKeys;
1281
1337
 
1282
1338
  // Non key Entity attributes
1283
1339
  csnProperties = _generateCSNEntityProperties(
1284
1340
  entityKeysList,
1285
1341
  entityPropertiesMap
1286
1342
  );
1343
+ csnProperties = csnKeys + csnProperties;
1344
+ //to remove additional ',\n' in case key datatype is undefined
1345
+ if (csnProperties && csnProperties.startsWith(",\n")) {
1346
+ csnProperties = csnProperties.substring(csnProperties.indexOf(",\n") + 2);
1347
+ }
1348
+
1287
1349
  csnEntity = csnEntity + csnProperties;
1288
1350
 
1289
1351
  // No keys and No properties found
@@ -1400,6 +1462,7 @@ function _getEntitesWithNamesFromEntitySets(
1400
1462
  : (name) => allEntities.indexOf(name) >= 0;
1401
1463
 
1402
1464
  const getEntitySetNames = entityWithName => {
1465
+ if (!entityWithName.name) return false;
1403
1466
  for (let i = 0; i < entityWithName.name.length; i++) {
1404
1467
  if (!isNameInEntitySet(entityWithName.name[i]))
1405
1468
  return false;
@@ -24,6 +24,8 @@ let functionImportToFunctionMap = new Multimap();
24
24
  let validEdmDatatypes = ['Edm.DateTimeOffset'];
25
25
  let jsonEntityContainerName;
26
26
  const ignoreObjects = ['$Reference']; // add all the objects that needs to be ignored for parsing.
27
+ const { warn } = require('@sap/cds/bin/utils/term');
28
+
27
29
  const MetadataConverterFactory = require('../import/utils/MetadataConverterFactory');
28
30
  const edmxncdsdatatype = {
29
31
  'Edm.String': 'cds.LargeString',
@@ -32,7 +34,7 @@ const edmxncdsdatatype = {
32
34
  'Edm.Int32': 'cds.Integer',
33
35
  'Edm.Int64': 'cds.Integer64',
34
36
  'Edm.Decimal': 'cds.DecimalFloat',
35
- 'Edm.DateTimeOffset': 'cds.Timestamp',
37
+ 'Edm.DateTimeOffset': 'cds.DateTime',
36
38
  'Edm.TimeOfDay': 'cds.Time',
37
39
  'Edm.Date': 'cds.Date',
38
40
  'Edm.Binary': 'cds.LargeBinary',
@@ -40,16 +42,18 @@ const edmxncdsdatatype = {
40
42
  'Edm.Byte': 'cds.Integer',
41
43
  'Edm.SByte': 'cds.Integer',
42
44
  'Edm.Double': 'cds.Double',
43
- 'Edm.Single': 'cds.DecimalFloat',
44
45
  // Special handling of data types
45
46
  'Edm.String_m': 'cds.String', // Max length
46
47
  'Edm.Decimal_p': 'cds.Decimal', // Precision, scale
47
- 'Edm.DateTime_f': 'cds.Date', // sap:display-format="Date"
48
- 'Edm.DateTimeOffset_f': 'cds.Date', // sap:display-format="Date"
48
+ //'Edm.DateTime_f': 'cds.Date', // sap:display-format="Date"
49
+ //'Edm.DateTimeOffset_f': 'cds.Date', // sap:display-format="Date"
49
50
  'Edm.Binary_m': 'cds.Binary', // Max Length
50
51
  'Edm.Byte_m': 'cds.Integer', // Max Length
51
- 'Edm.Double_p': 'cds.Double' // Precision, scale
52
-
52
+ 'Edm.Double_p': 'cds.Double', // Precision, scale
53
+ // Special handling with annotations
54
+ "Edm.Single_a": "cds.Double",
55
+ "Edm.Stream_a" : "cds.LargeBinary",
56
+ "Edm.DateTimeOffset_a" : "cds.Timestamp"
53
57
  };
54
58
 
55
59
  function _isJson(edmx) {
@@ -137,6 +141,15 @@ function generatePropertyCsn(propertyType, isPrimaryKey) {
137
141
  property.type = 'cds.String'; // if type is missing, then it is String type
138
142
  }
139
143
  property.length = propertyType.$MaxLength;
144
+ } else if(_isValidDataType(propertyType.$Type)) {
145
+ if(propertyType.$Precision && propertyType.$Precision > 0)
146
+ {
147
+ property.type = edmxncdsdatatype[propertyType.$Type + '_a'];
148
+ property["@odata.precision"] = propertyType.$Precision;
149
+ } else {
150
+ property.type = edmxncdsdatatype[propertyType.$Type];
151
+ property["@odata.precision"] = 0;
152
+ }
140
153
  } else if (propertyType.$Precision && !_isValidDataType(propertyType.$Type)) {
141
154
  property.type = edmxncdsdatatype[propertyType.$Type + '_p'];
142
155
  property.precision = propertyType.$Precision;
@@ -146,11 +159,19 @@ function generatePropertyCsn(propertyType, isPrimaryKey) {
146
159
  } else {
147
160
  property.scale = propertyType.$Scale;
148
161
  }
162
+ } else if (edmxncdsdatatype[propertyType.$Type + "_a"]) {
163
+ property.type = edmxncdsdatatype[propertyType.$Type + "_a"];
149
164
  } else if (propertyType.$Type) {
150
165
  property.type = edmxncdsdatatype[propertyType.$Type];
151
166
  } else{
152
167
  property.type = 'cds.LargeString'; // if type is missing, then it is String type
153
168
  }
169
+
170
+ if(edmxncdsdatatype[propertyType.$Type + '_a'])
171
+ {
172
+ property["@odata.type"] = propertyType.$Type;
173
+ }
174
+
154
175
  return property;
155
176
  }
156
177
 
@@ -175,7 +196,8 @@ function _parseAssociationProperty(foreignReference, associationNode, mockServer
175
196
  let data;
176
197
  let ref;
177
198
  associationProperty.type = 'cds.Association';
178
- associationProperty.doc = 'Please add an ON condition\n';
199
+ // annotation for ON condition
200
+ associationProperty["@cds.ambiguous"] = 'missing on condition?';
179
201
  // associationProperty.target = associationNode.$Type;
180
202
  if (mockServerUc && entitySetToEntityTypeMap && entitySetToEntityTypeMap.get(associationNode.$Type)) {
181
203
  if (entitySetToEntityTypeMap.get(associationNode.$Type).length > 1) {
@@ -267,7 +289,7 @@ function _generateCSNForEntityType(entityTypes, ignorePersistenceSkip, mockServe
267
289
  for (j = 0; j < curKey.length; j++) {
268
290
  keySet.push(curKey[j]);
269
291
  }
270
- } else if (!element[key][property].$Type || edmxncdsdatatype[element[key][property].$Type]) {
292
+ } else if (!element[key][property].$Type || edmxncdsdatatype[element[key][property].$Type] || edmxncdsdatatype[element[key][property].$Type + "_a"]) {
271
293
  propertyType = element[key][property];
272
294
  if (keySet.includes(property)) {
273
295
  entityCsn[key].elements[property] = generatePropertyCsn(propertyType, true);
@@ -291,6 +313,9 @@ function _generateCSNForEntityType(entityTypes, ignorePersistenceSkip, mockServe
291
313
  // for TypeDefinitions
292
314
  propertyType = element[key][property];
293
315
  entityCsn[key].elements[property] = _generateTypeDefinitionPropertyCsn(propertyType);
316
+ } else {
317
+ let message = '"' + element[key][property].$Type + '" is not supported (in element:"' + property + '")';
318
+ console.log(warn(message));
294
319
  }
295
320
  }
296
321
  }
@@ -500,19 +525,22 @@ function _parseBounded(csnDefs, flag) {
500
525
  let paramType ={};
501
526
  _includeExternalNamespaceAnnotation(paramObj,paramType);
502
527
  //check if the parameter type is pre-defined, undefined or custom defined
503
- if (edmxncdsdatatype[paramObj.$Type])
528
+ if (edmxncdsdatatype[paramObj.$Type] || edmxncdsdatatype[paramObj.$Type + "_a"])
504
529
  paramType = generatePropertyCsn(paramObj, false);
505
530
  else {
506
531
  let type = _getDatatype(paramObj.$Type);
507
532
  if(type) paramType["type"] = type;
508
533
  }
509
- if (paramType) {
534
+ if (paramType.type) {
510
535
  // check if parameter type is a collection
511
536
  if (paramObj.$Collection) {
512
537
  csnDefs[boundedEntityName].actions[name].params[paramName] = {};
513
538
  csnDefs[boundedEntityName].actions[name].params[paramName].items = paramType;
514
539
  } else
515
540
  csnDefs[boundedEntityName].actions[name].params[paramName] = paramType;
541
+ } else {
542
+ let message = '"' + paramObj.$Type + '" is not supported (in element:"' + name + '")';
543
+ console.log(warn(message));
516
544
  }
517
545
  }
518
546
 
@@ -527,20 +555,23 @@ function _parseBounded(csnDefs, flag) {
527
555
  if (obj[j].$ReturnType) {
528
556
  let returnType={};
529
557
  // check if the return type is pre-defined, undefined or custom defined
530
- if (edmxncdsdatatype[obj[j].$ReturnType.$Type])
558
+ if (edmxncdsdatatype[obj[j].$ReturnType.$Type] || edmxncdsdatatype[obj[j].$ReturnType.$Type + "_a"])
531
559
  returnType = generatePropertyCsn(obj[j].$ReturnType, false);
532
560
  else {
533
561
  let type = _getDatatype(obj[j].$ReturnType.$Type);
534
562
  _includeExternalNamespaceAnnotation(obj[j].$ReturnType,returnType);
535
563
  if(type) returnType["type"] = type ;
536
564
  }
537
- if (returnType) {
565
+ if (returnType.type) {
538
566
  csnDefs[boundedEntityName].actions[name].returns = {};
539
567
  // check if return type is a collection
540
568
  if (obj[j].$ReturnType.$Collection)
541
569
  csnDefs[boundedEntityName].actions[name].returns.items = returnType;
542
570
  else
543
571
  csnDefs[boundedEntityName].actions[name].returns = returnType;
572
+ } else {
573
+ let message = '"' + obj[j].$ReturnType.$Type + '" is not supported (in return type)';
574
+ console.log(warn(message));
544
575
  }
545
576
  }
546
577
  }
@@ -592,9 +623,12 @@ function _generateCSNForComplexType(schemaData) {
592
623
  }
593
624
  Object.keys(cTypes[element]).forEach(property => { // cTypes[element][property].$Type.startsWith('Edm.')
594
625
  if (cTypes[element][property] instanceof Object) {
595
- if (!cTypes[element][property].$Type || edmxncdsdatatype[cTypes[element][property].$Type] ) {
626
+ if (!cTypes[element][property].$Type || edmxncdsdatatype[cTypes[element][property].$Type] || edmxncdsdatatype[cTypes[element][property].$Type + "_a"]) {
596
627
  propertyType = cTypes[element][property];
597
628
  complexCsn[element].elements[property] = generatePropertyCsn(propertyType, false);
629
+ } else {
630
+ let message = '"' + cTypes[element][property].$Type + '" is not supported (in element:"' + property + '")';
631
+ console.log(warn(message));
598
632
  }
599
633
  } else if (complexTypes[cTypes[element][property].$Type]) {
600
634
  propertyType = cTypes[element][property];
@@ -653,14 +687,13 @@ function _parseUnbounded(schemaData, flag) {
653
687
  let typeProperties = {};
654
688
  _includeExternalNamespaceAnnotation(objData.$Parameter[i],typeProperties);
655
689
  // check if the parameter type is pre-defined, undefined or custom defined
656
- if (edmxncdsdatatype[objData.$Parameter[i].$Type]) {
690
+ if (edmxncdsdatatype[objData.$Parameter[i].$Type] || edmxncdsdatatype[objData.$Parameter[i].$Type + "_a"]) {
657
691
  const parameterProperties = generatePropertyCsn(objData.$Parameter[i], false);
658
692
  ({type, ...typeProperties} = parameterProperties);
659
693
  } else {
660
694
  type = _getDatatype(objData.$Parameter[i].$Type);
661
695
  }
662
696
  if (type) {
663
-
664
697
  // Adds type properties like scale, precision, etc if any
665
698
  const parameterObj = Object.keys(typeProperties).length > 0 ? { type, ...typeProperties } : { type };
666
699
 
@@ -670,6 +703,9 @@ function _parseUnbounded(schemaData, flag) {
670
703
  else
671
704
  obj[objType].params[objData.$Parameter[i].$Name] = parameterObj;
672
705
 
706
+ } else {
707
+ let message = '"' + objData.$Parameter[i].$Type + '" is not supported (in element:"' + temp + '")';
708
+ console.log(warn(message));
673
709
  }
674
710
  }
675
711
  }
@@ -682,14 +718,14 @@ function _parseUnbounded(schemaData, flag) {
682
718
  if (objData.$ReturnType && Object.keys(objData.$ReturnType).length > 0 && obj) {
683
719
  let returnValue = {};
684
720
  // check if the return type is pre-defined, undefined or custom defined
685
- if (edmxncdsdatatype[objData.$ReturnType.$Type]) {
721
+ if (edmxncdsdatatype[objData.$ReturnType.$Type] || edmxncdsdatatype[objData.$ReturnType.$Type + "_a"]) {
686
722
  returnValue = generatePropertyCsn(objData.$ReturnType, false);
687
723
  } else {
688
724
  let type = _getDatatype(objData.$ReturnType.$Type);
689
725
  _includeExternalNamespaceAnnotation(objData.$ReturnType,returnValue);
690
726
  if(type) returnValue["type"] = type;
691
727
  }
692
- if (returnValue) {
728
+ if (returnValue.type) {
693
729
  obj[objType].returns = {};
694
730
  // check if return type is a collection
695
731
  if (objData.$ReturnType.$Collection) {
@@ -697,6 +733,9 @@ function _parseUnbounded(schemaData, flag) {
697
733
  obj[objType].returns.items = returnValue;
698
734
  } else
699
735
  obj[objType].returns = returnValue;
736
+ } else {
737
+ let message = '"' + objData.$ReturnType.$Type + '" is not supported (in return type of' + temp + ')';
738
+ console.log(warn(message));
700
739
  }
701
740
  }
702
741
  }
@@ -826,7 +865,7 @@ function _checkAnnotationTarget(annotation, cdsDefs , str, no_of_terms){
826
865
  _checkAnnotatationTerm(annotation,cdsDefs[path[0]],no_of_terms,str);
827
866
  } else{
828
867
  let path1 = path[1].split('/');
829
- if(cdsDefs[path[0]]){
868
+ if(cdsDefs[path[0]] && cdsDefs[path[0]]["params"]){
830
869
  _checkAnnotatationTerm(annotation,cdsDefs[path[0]]["params"][path1[1]],no_of_terms,str);
831
870
  }
832
871
  }
package/lib/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  const cds = require ('@sap/cds')
2
- const get_compile = Reflect.getOwnPropertyDescriptor(cds,'compile').get
2
+ const compile_desc = Reflect.getOwnPropertyDescriptor(cds,'compile')
3
3
 
4
4
  // extending cds to lazy-load additional submodules provided by cds-dk
5
5
  module.exports = Object.defineProperties (cds, {
@@ -9,10 +9,11 @@ module.exports = Object.defineProperties (cds, {
9
9
  compile: {enumerable:true, get:()=> {
10
10
  // lazy-extending cds.compile.to only when cds.compile getter is invoked
11
11
  // otherwise we might cause cds.env being invoked too early.
12
- const compile = get_compile.call(cds)
13
- Object.defineProperties (compile.to, {
14
- openapi: {enumerable:true, get:()=> require('./compile/openapi')}
15
- })
12
+ const compile = compile_desc.value || compile_desc.get.call(cds)
13
+ if (!Reflect.getOwnPropertyDescriptor(compile.to, 'openapi'))
14
+ Object.defineProperties (compile.to, {
15
+ openapi: {enumerable:true, get:()=> require('./compile/openapi')}
16
+ })
16
17
  return compile
17
18
  }},
18
19
  })
@@ -1,6 +1,6 @@
1
1
  const os = require('os');
2
2
 
3
- const MAVEN_ARCHETYPE_VERSION = '1.20.0';
3
+ const MAVEN_ARCHETYPE_VERSION = '1.21.0';
4
4
 
5
5
  const constants = {
6
6
  IS_WIN: (os.platform() === 'win32'),
@@ -41,7 +41,7 @@ const constants = {
41
41
  MAVEN_ARCHETYPE_HELP: `https://cap.cloud.sap/docs/java/development/#the-maven-archetype`,
42
42
  MAVEN_INSTALL_HELP: `https://maven.apache.org/install.html`,
43
43
  PYTHON: 'https://www.python.org/downloads/',
44
- PYTHON_PIP: 'https://packaging.python.org/guides/',
44
+ PYTHON_PIP: 'https://packaging.python.org/en/latest/guides/',
45
45
  VSCODE: 'https://code.visualstudio.com/',
46
46
  VSCODE_NBVIEWER: 'https://marketplace.visualstudio.com/items?itemName=ms-python.python',
47
47
  VSCODE_ESLINT: 'https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint'
package/lib/init/index.js CHANGED
@@ -6,6 +6,7 @@ const term = require('../util/term');
6
6
  const Spinner = require('./util/spinner');
7
7
 
8
8
  const { OPTIONS_PRIORITY, COMMAND_ADD, COMMAND_INIT,
9
+ // eslint-disable-next-line no-unused-vars
9
10
  OPTION_HANA, OPTION_JAVA, OPTION_MTA, OPTION_MTX, OPTION_NODEJS,
10
11
  OPTION_PIPELINE, OPTION_SAMPLES, OPTION_CF_MANIFEST, PROJECT_FILES, REGEX_PROJECT_NAME } = require('./constants');
11
12
 
@@ -11,16 +11,12 @@ module.exports = class DataTemplate extends TemplateBase {
11
11
  async run() {
12
12
  const env = await this.getEnv();
13
13
 
14
- const prefix = (typeof this.options.for === 'string') // --for <prefix>
15
- ? this.options.for
16
- : '';
17
- const prefixedWith = (definition) => definition.name === prefix || definition.name.startsWith(prefix);
18
-
19
14
  let dest = (typeof this.options.out === 'string') // target folder
20
15
  ? this.options.out
21
16
  : getDefaultTargetFolder(env, this.projectPath);
22
17
  dest = resolve(this.projectPath, dest);
23
18
 
19
+ const nameFilter = asRegex(this.options.for)
24
20
  const force = this.options.force;
25
21
  const logger = this.logger;
26
22
 
@@ -35,7 +31,7 @@ module.exports = class DataTemplate extends TemplateBase {
35
31
  csn = cds.reflect(csn); // reflected model (adds additional helper functions)
36
32
 
37
33
  csn.all('entity')
38
- .filter(prefixedWith)
34
+ .filter (e => e.name.match(nameFilter)) // --for prefix|regex
39
35
  .filter (e => !e.query) // exclude entities with queries (projection on, select from ...)
40
36
  .filter (e => e.name !== 'DRAFT.DraftAdministrativeData' && !e.name.endsWith('.drafts')) // exclude draft stuff
41
37
  .forEach(e => processEntity(e, dest, this.projectPath, csn, force, logger));
@@ -53,6 +49,22 @@ function includeExternalEntities(model, logger) {
53
49
  return model
54
50
  }
55
51
 
52
+ function asRegex(spec) {
53
+ if (typeof spec === 'string') {
54
+ try {
55
+ if (spec.match(/[\^$|*]/))
56
+ return new RegExp(spec)
57
+ else { // no meta chars -> prefix semantics
58
+ spec = spec.replace(/\./g, '\\.') // escape dot
59
+ return new RegExp('^'+spec+'.*')
60
+ }
61
+ } catch (err) {
62
+ throw new Error (err.message) // user error, so cut off stack trace
63
+ }
64
+ }
65
+ return /.*/
66
+ }
67
+
56
68
  function processEntity (entity, dest, projectPath, csn, force, logger) {
57
69
  let dataFileName;
58
70
  const namespace = getNamespace(csn, entity.name);
@@ -0,0 +1,5 @@
1
+ [
2
+ "src/gen/**/*.hdbview",
3
+ "src/gen/**/*.hdbindex",
4
+ "src/gen/**/*.hdbconstraint"
5
+ ]
@@ -3,6 +3,9 @@
3
3
  "dependencies": {
4
4
  "@sap/hdi-deploy": "^4"
5
5
  },
6
+ "engines": {
7
+ "node": "^16"
8
+ },
6
9
  "scripts": {
7
10
  "start": "node node_modules/@sap/hdi-deploy/deploy.js"
8
11
  }