@sap/cds-dk 4.3.3 → 4.5.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 (47) hide show
  1. package/CHANGELOG.md +62 -1
  2. package/bin/activate.js +1 -2
  3. package/bin/deploy/index.js +1 -1
  4. package/bin/deploy/to-sqlite.js +2 -2
  5. package/bin/extend.js +2 -4
  6. package/bin/help.js +1 -1
  7. package/bin/login.js +7 -8
  8. package/bin/logout.js +1 -2
  9. package/bin/repl.js +1 -1
  10. package/bin/watch.js +12 -8
  11. package/lib/client/activate.js +243 -0
  12. package/lib/client/auth_manager.js +115 -0
  13. package/lib/client/base_command.js +55 -0
  14. package/lib/client/extend.js +179 -0
  15. package/lib/client/helper/cf_helper.js +186 -0
  16. package/lib/client/helper/dependency_helper.js +26 -0
  17. package/lib/client/helper/env_helper.js +4 -0
  18. package/lib/client/helper/fs_helper.js +83 -0
  19. package/lib/client/helper/logging.js +37 -0
  20. package/lib/client/helper/question.js +50 -0
  21. package/lib/client/helper/string_helper.js +53 -0
  22. package/lib/client/helper/url_helper.js +17 -0
  23. package/lib/client/index.js +14 -0
  24. package/lib/client/params.js +435 -0
  25. package/lib/client/settings_manager.js +526 -0
  26. package/lib/import/index.js +17 -38
  27. package/lib/import/message.js +6 -7
  28. package/lib/import/v2parser.js +340 -64
  29. package/lib/import/v4parser.js +346 -59
  30. package/lib/init/constants.js +1 -1
  31. package/lib/init/index.js +13 -10
  32. package/lib/init/template/data/index.js +38 -46
  33. package/lib/init/template/hana/index.js +2 -2
  34. package/lib/init/template/lint/files/.eslint/tests/no-entity-moo/fixed/schema.cds +4 -0
  35. package/lib/init/template/lint/files/.eslint/tests/no-entity-moo/invalid/schema.cds +4 -0
  36. package/lib/init/template/lint/files/.eslint/tests/no-entity-moo/test.js +10 -0
  37. package/lib/init/template/lint/files/.eslint/tests/no-entity-moo/valid/schema.cds +6 -0
  38. package/lib/init/template/lint/index.js +8 -6
  39. package/lib/init/template/mta/projectReader.js +8 -5
  40. package/lib/init/template/nodejs/files/.vscode/extensions.json +1 -1
  41. package/lib/init/template/nodejs/index.js +1 -8
  42. package/lib/init/util/logger.js +1 -1
  43. package/lib/lint/Linter.js +82 -65
  44. package/lib/lint/io.js +9 -33
  45. package/npm-shrinkwrap.json +6327 -11301
  46. package/package.json +6 -7
  47. package/lib/init/template/lint/files/.eslint/tests/no-entity-moo.test.js +0 -34
@@ -9,11 +9,14 @@ let allEntities = [];
9
9
  let allEntitiesMC = [];
10
10
  let allEntitySetMap = {};
11
11
  let allEntitySetMapMC = {};
12
+ let allFunctionImports = [];
13
+ let allFunctionImportsMap = {};
12
14
  let allAssociations = {};
13
15
  let allAssociationSets = {};
14
16
  let allComplexTypes = {};
17
+ let allComplexTypeDocs = {};
15
18
  let allInheritedComplexTypes = {};
16
- let getMessages = require("./message");
19
+ let messages = require("./message").getMessages();
17
20
  let versionInfo = require('../../package.json').version;
18
21
 
19
22
  let edmxncdsdatatype = {
@@ -47,16 +50,15 @@ function _initialize() {
47
50
  allEntitiesMC.length = 0;
48
51
  allEntitySetMap = {};
49
52
  allEntitySetMapMC = {};
53
+ allFunctionImports.length = 0;
54
+ allFunctionImportsMap = {};
50
55
  allAssociations = {};
51
56
  allAssociationSets = {};
52
57
  allComplexTypes = {};
58
+ allComplexTypeDocs = {};
53
59
  allInheritedComplexTypes = {};
54
60
  }
55
61
 
56
- function getNamespace() {
57
- return serviceNamespace;
58
- }
59
-
60
62
  function _isValidEDMX(jsonObj) {
61
63
  let isValid = false;
62
64
  let edmx;
@@ -81,7 +83,7 @@ function _hasEntityContainer(jsonObj) {
81
83
  let isEntityContainerPresent = !!jsonObj["edmx:Edmx"]["edmx:DataServices"]
82
84
  .Schema.EntityContainer;
83
85
  if (!isEntityContainerPresent) {
84
- throw new Error(getMessages().MISSING_ENTITY_CONTAINER);
86
+ throw new Error(messages.MISSING_ENTITY_CONTAINER);
85
87
  }
86
88
  return isEntityContainerPresent;
87
89
  }
@@ -89,7 +91,7 @@ function _hasEntityContainer(jsonObj) {
89
91
  function _hasEntitySet(jsonObj) {
90
92
  let isEntitySetPresent = !!jsonObj['edmx:Edmx']['edmx:DataServices'].Schema.EntityContainer.EntitySet;
91
93
  if (!isEntitySetPresent) {
92
- throw new Error(getMessages().MISSING_ENTITY_SETS);
94
+ throw new Error(messages.MISSING_ENTITY_SETS);
93
95
  }
94
96
  return isEntitySetPresent;
95
97
  }
@@ -99,7 +101,7 @@ function _isValidEDMXProvided(jsonObj) {
99
101
  if (_isValidEDMX(jsonObj)) {
100
102
  isValid = true;
101
103
  } else {
102
- throw new Error(getMessages().INVALID_EDMX_METADATA);
104
+ throw new Error(messages.INVALID_EDMX_METADATA);
103
105
  }
104
106
  return isValid;
105
107
  }
@@ -119,7 +121,7 @@ function _getServiceNameSpace(jsonObj) {
119
121
  if (Array.isArray(schemaArr)) {
120
122
  // TODO: Consider multiple schema.
121
123
  schema = schemaArr[0];
122
- // throw (getMessages().MULTIPLE_SCHEMA_FOUND);
124
+ // throw (messages.MULTIPLE_SCHEMA_FOUND);
123
125
  }
124
126
  Object.keys(schema).forEach((key) => {
125
127
  if (key === "_attributes") {
@@ -193,7 +195,9 @@ function _extractEntityFromEntitySet(entitySet) {
193
195
  Object.keys(entitySet).forEach((key) => {
194
196
  if (key === "_attributes") {
195
197
  allEntitySetMap[entitySet[key].Name] = entitySet[key].EntityType;
196
- allEntitySetMapMC[entitySet[key].EntityType] = entitySet[key].Name;
198
+ if (allEntitySetMapMC[entitySet[key].EntityType] === undefined)
199
+ allEntitySetMapMC[entitySet[key].EntityType] = [];
200
+ allEntitySetMapMC[entitySet[key].EntityType].push(entitySet[key].Name);
197
201
  entityName = _extractEntityFromNamespace(entitySet[key].EntityType);
198
202
  allEntities.push(entityName);
199
203
  allEntitiesMC.push(entitySet[key].Name);
@@ -214,6 +218,103 @@ function _extractAllEntityFromEntitySets(entitySets) {
214
218
  }
215
219
  }
216
220
 
221
+ function _extractNameFromFunctionImport(entityName) {
222
+ let entityId = "";
223
+ let pos = entityName.lastIndexOf("_");
224
+ if (pos < 0) {
225
+ return entityName;
226
+ }
227
+ entityId = entityName.substring(pos + 1);
228
+ return entityId;
229
+ }
230
+
231
+ function _getFunctionAttributes(functionImport, serviceNamespaceParam)
232
+ {
233
+ let funcAttributes = [];
234
+ if(functionImport["_attributes"])
235
+ {
236
+ funcAttributes.push(serviceNamespaceParam + _extractNameFromFunctionImport(functionImport["_attributes"].Name));
237
+ funcAttributes.push(functionImport["_attributes"]["m:HttpMethod"]);
238
+ if(functionImport["_attributes"].ReturnType)
239
+ {
240
+ funcAttributes.push(functionImport["_attributes"].ReturnType);
241
+ } else {
242
+ funcAttributes.push(-1);
243
+ }
244
+ }
245
+
246
+ if(functionImport["Parameter"])
247
+ {
248
+ funcAttributes.push(functionImport["Parameter"]);
249
+ } else {
250
+ funcAttributes.push(-1);
251
+ }
252
+
253
+ if(functionImport["Documentation"])
254
+ {
255
+ funcAttributes.push(_parseDocumentationTag(functionImport["Documentation"]));
256
+ } else {
257
+ funcAttributes.push(-1);
258
+ }
259
+
260
+ return funcAttributes;
261
+ }
262
+
263
+ function _extractFunctionImport(functionImport, serviceNamespaceParam)
264
+ {
265
+ //extracting the bounded and unbounded function import
266
+ let boundedFunctionImports = [];
267
+ let entityName;
268
+ Object.keys(functionImport).forEach((key) => {
269
+ if(key === "_attributes") {
270
+ if(functionImport[key]["sap:action-for"])
271
+ {
272
+ //storing bounded function imports
273
+ entityName = _extractEntityFromNamespace(functionImport[key]["sap:action-for"]);
274
+ boundedFunctionImports = (allFunctionImportsMap[entityName]) ? allFunctionImportsMap[entityName] : [];
275
+ boundedFunctionImports.push(_getFunctionAttributes(functionImport,""));
276
+ allFunctionImportsMap[entityName] = boundedFunctionImports;
277
+ }
278
+ else
279
+ {
280
+ //storing unbounded function imports
281
+ allFunctionImports.push(_getFunctionAttributes(functionImport,serviceNamespaceParam + "."));
282
+ }
283
+ }
284
+ });
285
+ }
286
+
287
+ //extracting the function imports from the metadata
288
+ function _extractAllFunctionImports(functionImports, serviceNamespaceParam)
289
+ {
290
+ let i;
291
+ if (functionImports.length) {
292
+ //Has many function imports in metadata
293
+ for (i = 0; i < functionImports.length; i++) {
294
+ _extractFunctionImport(functionImports[i], serviceNamespaceParam);
295
+ }
296
+ } else {
297
+ //Has only one function import in metadata
298
+ _extractFunctionImport(functionImports, serviceNamespaceParam);
299
+ }
300
+ }
301
+
302
+ // to parse the documentation tag
303
+ function _parseDocumentationTag(documentedContent) {
304
+ let documentation = "", text = "";
305
+ if (documentedContent.Summary && documentedContent.Summary._text) {
306
+ text = documentedContent.Summary._text.replace(/(?:\\[rn]|[\r\n]+)+/gm, "\\n");
307
+ documentation = text;
308
+ }
309
+ if (documentedContent.LongDescription && documentedContent.LongDescription._text) {
310
+ if (documentedContent.Summary)
311
+ documentation += "\\n\\n";
312
+ text = documentedContent.LongDescription._text.replace(/(?:\\[rn]|[\r\n]+)+/gm, "\\n");
313
+ documentation += text;
314
+ }
315
+ return documentation;
316
+ }
317
+
217
318
  function _extractComplexType(complexType, serviceNamespaceParam) {
218
319
  let complexTypeKey = "";
219
320
  let baseType = "";
@@ -225,6 +326,8 @@ function _extractComplexType(complexType, serviceNamespaceParam) {
225
326
  baseType = complexType[key].BaseType;
226
327
  } else if (key === "Property") {
227
328
  properties = complexType.Property;
329
+ } else if (key === "Documentation") {
330
+ allComplexTypeDocs[complexTypeKey] = _parseDocumentationTag(complexType.Documentation);
228
331
  }
229
332
  });
230
333
  allComplexTypes[complexTypeKey] = properties;
@@ -254,11 +357,12 @@ function _getServiceEntityProperty(
254
357
  scale,
255
358
  displayFormat,
256
359
  isKey,
257
- documentation
360
+ documentation,
361
+ isCollection
258
362
  ) {
259
363
  let cdsDataType = null;
260
364
  let hasInvalidPrecision = false;
261
- let propertyJson;
365
+ let propertyJson='';
262
366
  if (length && length > 0) {
263
367
  cdsDataType = edmxncdsdatatype[dataType + "_m"];
264
368
  } else if (precision && precision > 0) {
@@ -284,11 +388,23 @@ function _getServiceEntityProperty(
284
388
  cdsDataType = dataType;
285
389
  }
286
390
 
287
- propertyJson = '"' + propertyName + '": {\n';
391
+ //Possibility of entity type or entity set as the data type
392
+ if (!cdsDataType && allEntitySetMapMC[dataType]) {
393
+ cdsDataType = serviceNamespace + "." + allEntitySetMapMC[dataType];
394
+ } else if(!cdsDataType && allEntitySetMap[_extractEntityFromNamespace(dataType)]) {
395
+ cdsDataType = dataType;
396
+ }
397
+
398
+ if(propertyName)
399
+ propertyJson = '"' + propertyName + '": {\n';
288
400
 
289
401
  if (isKey) {
290
402
  propertyJson = propertyJson + '"key": true,\n';
291
403
  }
404
+ if(isCollection === 1)
405
+ {
406
+ propertyJson = propertyJson + '"items": { \n'
407
+ }
292
408
  propertyJson = propertyJson + '"type":"' + cdsDataType + '"';
293
409
  if (length && length > 0) {
294
410
  propertyJson = propertyJson + ',\n"length":' + length;
@@ -300,10 +416,16 @@ function _getServiceEntityProperty(
300
416
  propertyJson = propertyJson + ',\n"scale":' + 0;
301
417
  }
302
418
  }
419
+ if(isCollection === 1)
420
+ {
421
+ propertyJson = propertyJson + '\n}'
422
+ }
303
423
  if(documentation != -1 && documentation != undefined){
304
424
  propertyJson = propertyJson + ',\n"doc":"' + documentation + '"';
305
425
  }
306
- propertyJson = propertyJson + "\n}";
426
+
427
+ if(propertyName)
428
+ propertyJson = propertyJson + "\n}";
307
429
  return propertyJson;
308
430
  }
309
431
 
@@ -312,12 +434,16 @@ function _getServiceComplexType(complexTypeKey, complexType) {
312
434
  let complexTypeProperty;
313
435
  let i;
314
436
  complexTypeCSN = complexTypeCSN + '"kind": "type",\n';
437
+ if (allComplexTypeDocs[complexTypeKey])
438
+ complexTypeCSN = complexTypeCSN + '"doc":' + `"${allComplexTypeDocs[complexTypeKey]}",` + "\n";
315
439
  complexTypeCSN = complexTypeCSN + '"elements": {\n';
316
440
  if (complexType) {
317
441
  if (complexType.length) {
318
442
  // More than one complex types
319
443
  for (i = 0; i < complexType.length; i++) {
320
444
  complexTypeProperty = complexType[i]._attributes;
445
+ if(complexType[i].Documentation)
446
+ complexTypeProperty.doc = _parseDocumentationTag(complexType[i].Documentation);
321
447
  complexTypeCSN =
322
448
  complexTypeCSN +
323
449
  _getServiceEntityProperty(
@@ -328,7 +454,8 @@ function _getServiceComplexType(complexTypeKey, complexType) {
328
454
  complexTypeProperty.Scale,
329
455
  complexTypeProperty["sap:display-format"],
330
456
  false,
331
- complexTypeProperty.doc
457
+ complexTypeProperty.doc,
458
+ -1
332
459
  );
333
460
  if (i !== complexType.length - 1) {
334
461
  complexTypeCSN = complexTypeCSN + ",\n";
@@ -339,6 +466,8 @@ function _getServiceComplexType(complexTypeKey, complexType) {
339
466
  } else {
340
467
  // Only one complex type
341
468
  complexTypeProperty = complexType._attributes;
469
+ if(complexType.Documentation)
470
+ complexTypeProperty.doc = _parseDocumentationTag(complexType.Documentation);
342
471
  complexTypeCSN =
343
472
  complexTypeCSN +
344
473
  _getServiceEntityProperty(
@@ -349,7 +478,8 @@ function _getServiceComplexType(complexTypeKey, complexType) {
349
478
  complexTypeProperty.Scale,
350
479
  complexTypeProperty["sap:display-format"],
351
480
  false,
352
- complexTypeProperty.doc
481
+ complexTypeProperty.doc,
482
+ -1
353
483
  );
354
484
  }
355
485
  }
@@ -387,6 +517,116 @@ function _getServiceComplexTypes() {
387
517
  return complexTypeCSN;
388
518
  }
389
519
 
520
+ function _parseParameter(parameter)
521
+ {
522
+ let csn = "";
523
+ let doc;
524
+ let isCollection = -1;
525
+ if(parameter.Documentation)
526
+ doc = _parseDocumentationTag(parameter.Documentation);
527
+ let type = parameter["_attributes"].Type;
528
+ if(type.substring(0,10) === 'Collection')
529
+ {
530
+ type = type.substring(11,type.length-1);
531
+ isCollection = 1;
532
+ }
533
+ csn = csn + _getServiceEntityProperty(parameter["_attributes"].Name,
534
+ type,
535
+ parameter["_attributes"].MaxLength,
536
+ parameter["_attributes"].Precision,
537
+ parameter["_attributes"].Scale,
538
+ parameter["_attributes"]["sap:display-format"],
539
+ false,
540
+ doc,
541
+ isCollection);
542
+ return csn;
543
+ }
544
+
545
+ function _parseParametersFunctionImport(parameters, isBounded) {
546
+ let csn = "";
547
+ let i = isBounded===1 ? 1 : 0;
548
+ if(parameters.length)
549
+ {
550
+ for(i;i<parameters.length;i++)
551
+ {
552
+ csn = csn + _parseParameter(parameters[i]);
553
+ if(i!== parameters.length - 1) {
554
+ csn = csn + ",\n";
555
+ } else {
556
+ csn = csn + "\n";
557
+ }
558
+ }
559
+ } else {
560
+ csn = csn + _parseParameter(parameters);
561
+ }
562
+
563
+ return csn;
564
+ }
565
+
566
+ function _getFunctionImport(functionImport,isBounded) {
567
+ let noValue;
568
+ let csn = "";
569
+ csn = csn + '"' + functionImport[0] + '": { \n';
570
+ csn = csn + '"kind": "';
571
+ if(functionImport[1] === "GET")
572
+ {
573
+ csn = csn + "function";
574
+ } else if(functionImport[1] === "POST")
575
+ {
576
+ csn = csn + "action";
577
+ }
578
+ csn = csn + '"';
579
+ if(functionImport[3] !== -1)
580
+ {
581
+ if(isBounded === 0 || (isBounded === 1 && functionImport[3] instanceof Array ))
582
+ {
583
+ csn = csn + ", \n";
584
+ csn = csn + '"params": { \n';
585
+ csn = csn + _parseParametersFunctionImport(functionImport[3],isBounded);
586
+ csn = csn + '\n }';
587
+ }
588
+ }
589
+ if(functionImport[2] !== -1)
590
+ {
591
+ csn = csn + ", \n";
592
+ csn = csn + '"returns": { \n';
593
+ let isCollection = -1;
594
+ if(functionImport[2].substring(0,10) === 'Collection')
595
+ {
596
+ functionImport[2] = functionImport[2].substring(11,functionImport[2].length-1);
597
+ isCollection = 1;
598
+ }
599
+ //return type
600
+ csn = csn + _getServiceEntityProperty(noValue,functionImport[2],noValue,noValue,noValue,noValue,noValue,noValue,isCollection);
601
+ csn = csn + '\n }';
602
+ }
603
+ if(functionImport[4] !== -1)
604
+ {
605
+ csn = csn + ',\n "doc": "' + functionImport[4] + '"';
606
+ }
607
+
608
+ csn = csn + "\n }";
609
+ return csn;
610
+ }
611
+
612
+ function _getAllFunctionImports(functionImports,isBounded) {
613
+ let functionImportCSN = "";
614
+ let i;
615
+ for(i=0; i<functionImports.length;i++)
616
+ {
617
+ functionImportCSN =
618
+ functionImportCSN +
619
+ _getFunctionImport(functionImports[i],isBounded);
620
+ if(i!== functionImports.length - 1) {
621
+ functionImportCSN = functionImportCSN + ",\n";
622
+ } else {
623
+ functionImportCSN = functionImportCSN + "\n";
624
+ }
625
+ }
626
+
627
+ return functionImportCSN;
628
+ }
629
+
390
630
  function _getEntityName(entity) {
391
631
  return entity._attributes.Name;
392
632
  }
@@ -458,42 +698,18 @@ function _parseEntityProperty(properties) {
458
698
  // Has more than one entities
459
699
  for (i = 0; i < properties.length; i++) {
460
700
  propAttributes = properties[i]._attributes;
461
- if(properties[i] && properties[i].Documentation)
462
- {
463
- propAttributes.doc="";
464
- if(properties[i].Documentation.Summary && properties[i].Documentation.Summary._text)
465
- propAttributes.doc = properties[i].Documentation.Summary._text;
466
- if(properties[i].Documentation.LongDescription && properties[i].Documentation.LongDescription._text)
467
- {
468
- if(properties[i].Documentation.Summary)
469
- propAttributes.doc += "\\n\\n"
470
- propAttributes.doc += properties[i].Documentation.LongDescription._text;
471
- }
472
-
473
- }
474
- retProperties[propAttributes.Name] = _getPropertyAttributes(
475
- propAttributes
476
- );
701
+ // if the property contains documentatin tag
702
+ if(properties[i] && properties[i].Documentation)
703
+ propAttributes.doc = _parseDocumentationTag(properties[i].Documentation);
704
+ retProperties[propAttributes.Name] = _getPropertyAttributes(propAttributes);
477
705
  }
478
706
  } else {
479
707
  // Has only one entity
480
708
  propAttributes = properties._attributes;
709
+ // if the property contains documentatin tag
481
710
  if(properties && properties.Documentation)
482
- {
483
- propAttributes.doc="";
484
- if(properties.Documentation.Summary && properties.Documentation.Summary._text)
485
- propAttributes.doc = properties.Documentation.Summary._text;
486
- if(properties.Documentation.LongDescription && properties.Documentation.LongDescription._text)
487
- {
488
- if(properties.Documentation.Summary)
489
- propAttributes.doc += "\\n\\n"
490
- propAttributes.doc += properties.Documentation.LongDescription._text;
491
- }
492
- }
493
-
494
- retProperties[propAttributes.Name] = _getPropertyAttributes(
495
- propAttributes
496
- );
711
+ propAttributes.doc = _parseDocumentationTag(properties.Documentation);
712
+ retProperties[propAttributes.Name] = _getPropertyAttributes(propAttributes);
497
713
  }
498
714
  return retProperties;
499
715
  }
@@ -506,11 +722,17 @@ function _parseNavigationProperty(navigationProperties) {
506
722
  // Has more than one navigation property
507
723
  for (i = 0; i < navigationProperties.length; i++) {
508
724
  navPropAttributes = navigationProperties[i]._attributes;
725
+ // if the property contains documentatin tag
726
+ if(navigationProperties[i] && navigationProperties[i].Documentation)
727
+ navPropAttributes.doc = _parseDocumentationTag(navigationProperties[i].Documentation);
509
728
  retNavProperties[navPropAttributes.Name] = navPropAttributes;
510
729
  }
511
730
  } else {
512
731
  // Has only one navigation property
513
732
  navPropAttributes = navigationProperties._attributes;
733
+ // if the property contains documentatin tag
734
+ if(navigationProperties && navigationProperties.Documentation)
735
+ navPropAttributes.doc = _parseDocumentationTag(navigationProperties.Documentation);
514
736
  retNavProperties[navPropAttributes.Name] = navPropAttributes;
515
737
  }
516
738
  return retNavProperties;
@@ -532,7 +754,8 @@ function _generateCSNEntityKeys(entityKeysList, entityPropertiesMap) {
532
754
  propAttributes[3],
533
755
  propAttributes[4],
534
756
  true,
535
- propAttributes[5]
757
+ propAttributes[5],
758
+ -1
536
759
  );
537
760
  if (i !== entityKeysList.length - 1) {
538
761
  csnEntity = csnEntity + ",\n";
@@ -569,7 +792,8 @@ function _generateCSNEntityProperties(entityKeysList, entityPropertiesMap) {
569
792
  propAttributes[3],
570
793
  propAttributes[4],
571
794
  false,
572
- propAttributes[5]
795
+ propAttributes[5],
796
+ -1
573
797
  );
574
798
  if (i !== entityProperties.length - 1) {
575
799
  csnEntity = csnEntity + ",\n";
@@ -850,6 +1074,7 @@ function _getServiceEntityNavigationProperty(navPropAttributes, mockServerUc) {
850
1074
  let csn = "";
851
1075
  let navPropName;
852
1076
  let relationshipName;
1077
+ let navPropDoc;
853
1078
  // var fromRole;
854
1079
  let toRole;
855
1080
  if (!navPropAttributes) {
@@ -859,8 +1084,12 @@ function _getServiceEntityNavigationProperty(navPropAttributes, mockServerUc) {
859
1084
  relationshipName = navPropAttributes.Relationship;
860
1085
  // fromRole = navPropAttributes.FromRole;
861
1086
  toRole = navPropAttributes.ToRole;
1087
+ navPropDoc = navPropAttributes.doc;
862
1088
 
863
1089
  csn = csn + '"' + navPropName + '": {\n';
1090
+ // if documentatin exists for navigation property
1091
+ if(navPropDoc)
1092
+ csn = csn + `"doc": "${navPropDoc}",` + "\n";
864
1093
  csn = csn + '"type": "cds.Association",\n';
865
1094
  csn =
866
1095
  csn +
@@ -918,7 +1147,8 @@ function _constructServiceEntity(
918
1147
  entityNavigationPropertiesMap,
919
1148
  entityAttributes,
920
1149
  ignorePersistenceSkip,
921
- mockServerUc
1150
+ mockServerUc,
1151
+ documentation
922
1152
  ) {
923
1153
  let serviceEntityName = serviceNamespaceParam + "." + entityName;
924
1154
  let csnEntity = '"' + serviceEntityName + '": {\n';
@@ -935,6 +1165,10 @@ function _constructServiceEntity(
935
1165
  ) {
936
1166
  csnEntity = csnEntity + '"abstract": true,\n';
937
1167
  }
1168
+ // if documentation exists for the entity
1169
+ if (documentation) {
1170
+ csnEntity = csnEntity + `"doc": "${documentation}",` + '\n';
1171
+ }
938
1172
  csnEntity = csnEntity + '"elements": {\n';
939
1173
 
940
1174
  // Key Entity attributes
@@ -968,6 +1202,21 @@ function _constructServiceEntity(
968
1202
  csnEntity =
969
1203
  csnEntity + '"includes": ["' + entityAttributes.BaseType + '"]\n';
970
1204
  }
1205
+
1206
+ //if the function import is bounded to entitySet
1207
+ if (allFunctionImportsMap[entityName])
1208
+ {
1209
+ csnEntity = csnEntity + ', \n "actions": {\n';
1210
+ csnEntity = csnEntity + _getAllFunctionImports(allFunctionImportsMap[entityName],1);
1211
+ csnEntity = csnEntity + "}";
1212
+ }
1213
+ else if (allFunctionImportsMap[_extractEntityFromNamespace(allEntitySetMap[entityName])]) //if the function import is bounded to entityType
1214
+ {
1215
+ csnEntity = csnEntity + ', \n "actions": {\n';
1216
+ csnEntity = csnEntity + _getAllFunctionImports(allFunctionImportsMap[_extractEntityFromNamespace(allEntitySetMap[entityName])],1);
1217
+ csnEntity = csnEntity + "}";
1218
+ }
1219
+
971
1220
  return csnEntity;
972
1221
  }
973
1222
 
@@ -982,6 +1231,7 @@ function _parseServiceEntity(
982
1231
  let entityKeysList;
983
1232
  let entityPropertiesMap;
984
1233
  let entityNavigationPropertiesMap;
1234
+ let documentation;
985
1235
  Object.keys(entity).forEach((key) => {
986
1236
  if (key === "_attributes") {
987
1237
  entityAttributes = _parseEntityAttributes(entity[key]);
@@ -990,9 +1240,9 @@ function _parseServiceEntity(
990
1240
  } else if (key.toUpperCase() === "Property".toUpperCase()) {
991
1241
  entityPropertiesMap = _parseEntityProperty(entity[key]);
992
1242
  } else if (key.toUpperCase() === "NavigationProperty".toUpperCase()) {
993
- entityNavigationPropertiesMap = _parseNavigationProperty(
994
- entity[key]
995
- );
1243
+ entityNavigationPropertiesMap = _parseNavigationProperty(entity[key]);
1244
+ } else if (key.toUpperCase() === "Documentation".toUpperCase()) {
1245
+ documentation = _parseDocumentationTag(entity[key]);
996
1246
  }
997
1247
  });
998
1248
  // No keys in entity
@@ -1024,7 +1274,8 @@ function _parseServiceEntity(
1024
1274
  entityNavigationPropertiesMap,
1025
1275
  entityAttributes,
1026
1276
  ignorePersistenceSkip,
1027
- mockServerUc
1277
+ mockServerUc,
1278
+ documentation
1028
1279
  );
1029
1280
  }
1030
1281
 
@@ -1038,18 +1289,26 @@ function _getEntitesWithNamesFromEntitySets(
1038
1289
  allEntitySetMapMC[
1039
1290
  serviceNamespaceParam + "." + _getEntityName(entity)
1040
1291
  ]
1041
- : (entity) => _getEntityName(entity);
1292
+ : (entity) => [_getEntityName(entity)];
1042
1293
 
1043
1294
  const isNameInEntitySet = mockServerUc
1044
1295
  ? (name) => allEntitiesMC.indexOf(name) >= 0
1045
1296
  : (name) => allEntities.indexOf(name) >= 0;
1046
1297
 
1298
+ const getEntitySetNames = entityWithName => {
1299
+ for (let i = 0; i < entityWithName.name.length; i++) {
1300
+ if (!isNameInEntitySet(entityWithName.name[i]))
1301
+ return false;
1302
+ }
1303
+ return true;
1304
+ };
1305
+
1047
1306
  return entityJson
1048
1307
  .map((entity) => ({
1049
1308
  entity,
1050
1309
  name: getEntityName(entity),
1051
1310
  }))
1052
- .filter((entityWithName) => isNameInEntitySet(entityWithName.name));
1311
+ .filter((entityWithName) => getEntitySetNames(entityWithName));
1053
1312
  }
1054
1313
 
1055
1314
  function _getServiceEntitites(
@@ -1067,17 +1326,18 @@ function _getServiceEntitites(
1067
1326
 
1068
1327
  if (entitiesWithNames.length) {
1069
1328
  return (
1070
- entitiesWithNames
1071
- .map((entityWithName) =>
1329
+ entitiesWithNames.map((entityWithName) =>
1330
+ entityWithName.name.map((entityName) =>
1072
1331
  _parseServiceEntity(
1073
1332
  serviceNamespaceParam,
1074
- entityWithName.name,
1333
+ entityName,
1075
1334
  entityWithName.entity,
1076
1335
  ignorePersistenceSkip,
1077
1336
  mockServerUc
1078
1337
  )
1079
1338
  )
1080
1339
  .join("},") + "}"
1340
+ )
1081
1341
  );
1082
1342
  }
1083
1343
  return "";
@@ -1115,6 +1375,13 @@ function _generateEDMXJSON2CSN(
1115
1375
  if (entitySets) {
1116
1376
  _extractAllEntityFromEntitySets(entitySets);
1117
1377
  }
1378
+ // Extract function imports
1379
+ const functionImports =
1380
+ jsonObj["edmx:Edmx"]["edmx:DataServices"].Schema.EntityContainer
1381
+ .FunctionImport;
1382
+ if(functionImports) {
1383
+ _extractAllFunctionImports(functionImports, serviceNamespaceParam);
1384
+ }
1118
1385
  // Extract complex types
1119
1386
  const complexTypes =
1120
1387
  jsonObj["edmx:Edmx"]["edmx:DataServices"].Schema.ComplexType;
@@ -1128,9 +1395,13 @@ function _generateEDMXJSON2CSN(
1128
1395
  const definitions = [];
1129
1396
 
1130
1397
  if (mockServerUc) {
1131
- definitions.push(
1132
- '"' + serviceNamespaceParam + '": {"kind": "service"}'
1133
- );
1398
+ let def = '"' + serviceNamespaceParam + '": {"kind": "service"';
1399
+ let schemaDoc = jsonObj["edmx:Edmx"]["edmx:DataServices"].Schema.Documentation;
1400
+ // if documentation exists for schema
1401
+ if(schemaDoc)
1402
+ def += ',\n' + `"doc": "${_parseDocumentationTag(schemaDoc)}"`;
1403
+ def += "}";
1404
+ definitions.push(def);
1134
1405
  }
1135
1406
 
1136
1407
  // If complex type exists
@@ -1138,6 +1409,12 @@ function _generateEDMXJSON2CSN(
1138
1409
  definitions.push(_getServiceComplexTypes());
1139
1410
  }
1140
1411
 
1412
+ //if there are unbounded function imports
1413
+ if(Object.keys(allFunctionImports).length > 0)
1414
+ {
1415
+ definitions.push(_getAllFunctionImports(allFunctionImports,0)); //passing 0 for unbounded actions/functions
1416
+ }
1417
+
1141
1418
  if (entityJson) {
1142
1419
  definitions.push(
1143
1420
  _getServiceEntitites(
@@ -1179,6 +1456,5 @@ function getEdmxv2CSN(
1179
1456
  }
1180
1457
 
1181
1458
  module.exports = {
1182
- getEdmxv2CSN,
1183
- getNamespace,
1459
+ getEdmxv2CSN
1184
1460
  };