@sap/cds-dk 4.4.2 → 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 (39) hide show
  1. package/CHANGELOG.md +24 -0
  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/login.js +7 -8
  7. package/bin/logout.js +1 -2
  8. package/bin/repl.js +1 -1
  9. package/bin/watch.js +12 -8
  10. package/lib/client/activate.js +243 -0
  11. package/lib/client/auth_manager.js +115 -0
  12. package/lib/client/base_command.js +55 -0
  13. package/lib/client/extend.js +179 -0
  14. package/lib/client/helper/cf_helper.js +186 -0
  15. package/lib/client/helper/dependency_helper.js +26 -0
  16. package/lib/client/helper/env_helper.js +4 -0
  17. package/lib/client/helper/fs_helper.js +83 -0
  18. package/lib/client/helper/logging.js +37 -0
  19. package/lib/client/helper/question.js +50 -0
  20. package/lib/client/helper/string_helper.js +53 -0
  21. package/lib/client/helper/url_helper.js +17 -0
  22. package/lib/client/index.js +14 -0
  23. package/lib/client/params.js +435 -0
  24. package/lib/client/settings_manager.js +526 -0
  25. package/lib/import/index.js +5 -18
  26. package/lib/import/v2parser.js +282 -27
  27. package/lib/import/v4parser.js +341 -54
  28. package/lib/init/constants.js +1 -1
  29. package/lib/init/index.js +13 -10
  30. package/lib/init/template/data/index.js +38 -46
  31. package/lib/init/template/hana/index.js +2 -2
  32. package/lib/init/template/lint/index.js +8 -6
  33. package/lib/init/template/mta/projectReader.js +8 -5
  34. package/lib/init/template/nodejs/files/.vscode/extensions.json +1 -1
  35. package/lib/init/template/nodejs/index.js +1 -8
  36. package/lib/lint/Linter.js +62 -60
  37. package/lib/lint/io.js +9 -33
  38. package/npm-shrinkwrap.json +7684 -12883
  39. package/package.json +4 -5
@@ -9,6 +9,8 @@ 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 = {};
@@ -48,6 +50,8 @@ function _initialize() {
48
50
  allEntitiesMC.length = 0;
49
51
  allEntitySetMap = {};
50
52
  allEntitySetMapMC = {};
53
+ allFunctionImports.length = 0;
54
+ allFunctionImportsMap = {};
51
55
  allAssociations = {};
52
56
  allAssociationSets = {};
53
57
  allComplexTypes = {};
@@ -55,10 +59,6 @@ function _initialize() {
55
59
  allInheritedComplexTypes = {};
56
60
  }
57
61
 
58
- function getNamespace() {
59
- return serviceNamespace;
60
- }
61
-
62
62
  function _isValidEDMX(jsonObj) {
63
63
  let isValid = false;
64
64
  let edmx;
@@ -195,7 +195,9 @@ function _extractEntityFromEntitySet(entitySet) {
195
195
  Object.keys(entitySet).forEach((key) => {
196
196
  if (key === "_attributes") {
197
197
  allEntitySetMap[entitySet[key].Name] = entitySet[key].EntityType;
198
- 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);
199
201
  entityName = _extractEntityFromNamespace(entitySet[key].EntityType);
200
202
  allEntities.push(entityName);
201
203
  allEntitiesMC.push(entitySet[key].Name);
@@ -216,15 +218,99 @@ function _extractAllEntityFromEntitySets(entitySets) {
216
218
  }
217
219
  }
218
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
+
219
302
  // to parse the documentation tag
220
- function _parseDocumentationTag(documentedContent){
221
- let documentation = "";
222
- if(documentedContent.Summary && documentedContent.Summary._text)
223
- documentation = documentedContent.Summary._text;
224
- if(documentedContent.LongDescription && documentedContent.LongDescription._text) {
225
- if(documentedContent.Summary)
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)
226
311
  documentation += "\\n\\n";
227
- documentation += documentedContent.LongDescription._text;
312
+ text = documentedContent.LongDescription._text.replace(/(?:\\[rn]|[\r\n]+)+/gm, "\\n");
313
+ documentation += text;
228
314
  }
229
315
  return documentation;
230
316
  }
@@ -271,11 +357,12 @@ function _getServiceEntityProperty(
271
357
  scale,
272
358
  displayFormat,
273
359
  isKey,
274
- documentation
360
+ documentation,
361
+ isCollection
275
362
  ) {
276
363
  let cdsDataType = null;
277
364
  let hasInvalidPrecision = false;
278
- let propertyJson;
365
+ let propertyJson='';
279
366
  if (length && length > 0) {
280
367
  cdsDataType = edmxncdsdatatype[dataType + "_m"];
281
368
  } else if (precision && precision > 0) {
@@ -301,11 +388,23 @@ function _getServiceEntityProperty(
301
388
  cdsDataType = dataType;
302
389
  }
303
390
 
304
- 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';
305
400
 
306
401
  if (isKey) {
307
402
  propertyJson = propertyJson + '"key": true,\n';
308
403
  }
404
+ if(isCollection === 1)
405
+ {
406
+ propertyJson = propertyJson + '"items": { \n'
407
+ }
309
408
  propertyJson = propertyJson + '"type":"' + cdsDataType + '"';
310
409
  if (length && length > 0) {
311
410
  propertyJson = propertyJson + ',\n"length":' + length;
@@ -317,10 +416,16 @@ function _getServiceEntityProperty(
317
416
  propertyJson = propertyJson + ',\n"scale":' + 0;
318
417
  }
319
418
  }
419
+ if(isCollection === 1)
420
+ {
421
+ propertyJson = propertyJson + '\n}'
422
+ }
320
423
  if(documentation != -1 && documentation != undefined){
321
424
  propertyJson = propertyJson + ',\n"doc":"' + documentation + '"';
322
425
  }
323
- propertyJson = propertyJson + "\n}";
426
+
427
+ if(propertyName)
428
+ propertyJson = propertyJson + "\n}";
324
429
  return propertyJson;
325
430
  }
326
431
 
@@ -349,7 +454,8 @@ function _getServiceComplexType(complexTypeKey, complexType) {
349
454
  complexTypeProperty.Scale,
350
455
  complexTypeProperty["sap:display-format"],
351
456
  false,
352
- complexTypeProperty.doc
457
+ complexTypeProperty.doc,
458
+ -1
353
459
  );
354
460
  if (i !== complexType.length - 1) {
355
461
  complexTypeCSN = complexTypeCSN + ",\n";
@@ -372,7 +478,8 @@ function _getServiceComplexType(complexTypeKey, complexType) {
372
478
  complexTypeProperty.Scale,
373
479
  complexTypeProperty["sap:display-format"],
374
480
  false,
375
- complexTypeProperty.doc
481
+ complexTypeProperty.doc,
482
+ -1
376
483
  );
377
484
  }
378
485
  }
@@ -410,6 +517,116 @@ function _getServiceComplexTypes() {
410
517
  return complexTypeCSN;
411
518
  }
412
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
+
413
630
  function _getEntityName(entity) {
414
631
  return entity._attributes.Name;
415
632
  }
@@ -537,7 +754,8 @@ function _generateCSNEntityKeys(entityKeysList, entityPropertiesMap) {
537
754
  propAttributes[3],
538
755
  propAttributes[4],
539
756
  true,
540
- propAttributes[5]
757
+ propAttributes[5],
758
+ -1
541
759
  );
542
760
  if (i !== entityKeysList.length - 1) {
543
761
  csnEntity = csnEntity + ",\n";
@@ -574,7 +792,8 @@ function _generateCSNEntityProperties(entityKeysList, entityPropertiesMap) {
574
792
  propAttributes[3],
575
793
  propAttributes[4],
576
794
  false,
577
- propAttributes[5]
795
+ propAttributes[5],
796
+ -1
578
797
  );
579
798
  if (i !== entityProperties.length - 1) {
580
799
  csnEntity = csnEntity + ",\n";
@@ -983,6 +1202,21 @@ function _constructServiceEntity(
983
1202
  csnEntity =
984
1203
  csnEntity + '"includes": ["' + entityAttributes.BaseType + '"]\n';
985
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
+
986
1220
  return csnEntity;
987
1221
  }
988
1222
 
@@ -1055,18 +1289,26 @@ function _getEntitesWithNamesFromEntitySets(
1055
1289
  allEntitySetMapMC[
1056
1290
  serviceNamespaceParam + "." + _getEntityName(entity)
1057
1291
  ]
1058
- : (entity) => _getEntityName(entity);
1292
+ : (entity) => [_getEntityName(entity)];
1059
1293
 
1060
1294
  const isNameInEntitySet = mockServerUc
1061
1295
  ? (name) => allEntitiesMC.indexOf(name) >= 0
1062
1296
  : (name) => allEntities.indexOf(name) >= 0;
1063
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
+
1064
1306
  return entityJson
1065
1307
  .map((entity) => ({
1066
1308
  entity,
1067
1309
  name: getEntityName(entity),
1068
1310
  }))
1069
- .filter((entityWithName) => isNameInEntitySet(entityWithName.name));
1311
+ .filter((entityWithName) => getEntitySetNames(entityWithName));
1070
1312
  }
1071
1313
 
1072
1314
  function _getServiceEntitites(
@@ -1084,17 +1326,18 @@ function _getServiceEntitites(
1084
1326
 
1085
1327
  if (entitiesWithNames.length) {
1086
1328
  return (
1087
- entitiesWithNames
1088
- .map((entityWithName) =>
1329
+ entitiesWithNames.map((entityWithName) =>
1330
+ entityWithName.name.map((entityName) =>
1089
1331
  _parseServiceEntity(
1090
1332
  serviceNamespaceParam,
1091
- entityWithName.name,
1333
+ entityName,
1092
1334
  entityWithName.entity,
1093
1335
  ignorePersistenceSkip,
1094
1336
  mockServerUc
1095
1337
  )
1096
1338
  )
1097
1339
  .join("},") + "}"
1340
+ )
1098
1341
  );
1099
1342
  }
1100
1343
  return "";
@@ -1132,6 +1375,13 @@ function _generateEDMXJSON2CSN(
1132
1375
  if (entitySets) {
1133
1376
  _extractAllEntityFromEntitySets(entitySets);
1134
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
+ }
1135
1385
  // Extract complex types
1136
1386
  const complexTypes =
1137
1387
  jsonObj["edmx:Edmx"]["edmx:DataServices"].Schema.ComplexType;
@@ -1159,6 +1409,12 @@ function _generateEDMXJSON2CSN(
1159
1409
  definitions.push(_getServiceComplexTypes());
1160
1410
  }
1161
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
+
1162
1418
  if (entityJson) {
1163
1419
  definitions.push(
1164
1420
  _getServiceEntitites(
@@ -1200,6 +1456,5 @@ function getEdmxv2CSN(
1200
1456
  }
1201
1457
 
1202
1458
  module.exports = {
1203
- getEdmxv2CSN,
1204
- getNamespace,
1459
+ getEdmxv2CSN
1205
1460
  };