@sap/cds-dk 8.1.1 → 8.2.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 (65) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/bin/bind.js +44 -11
  3. package/bin/cds-tsx.js +2 -0
  4. package/bin/cds.js +5 -3
  5. package/bin/compile/index.js +2 -1
  6. package/bin/deploy/index.js +19 -1
  7. package/bin/import.js +13 -4
  8. package/bin/init.js +1 -1
  9. package/bin/version.js +1 -0
  10. package/bin/watch.js +2 -2
  11. package/lib/bind/bindingManager.js +1 -1
  12. package/lib/bind/cfKeyProvider.js +1 -1
  13. package/lib/build/buildTaskProviderFactory.js +9 -3
  14. package/lib/build/plugins/helm/files/subcharts/content-deployment/Chart.yaml +1 -1
  15. package/lib/build/plugins/helm/files/subcharts/content-deployment/values.yaml +1 -1
  16. package/lib/build/plugins/helm/files/subcharts/service-instance/Chart.yaml +1 -1
  17. package/lib/build/plugins/helm/files/subcharts/service-instance/values.yaml +1 -1
  18. package/lib/build/plugins/helm/files/subcharts/web-application/Chart.yaml +1 -1
  19. package/lib/build/plugins/helm/files/subcharts/web-application/templates/deployment.yaml +2 -2
  20. package/lib/build/plugins/helm/files/subcharts/web-application/values.yaml +1 -1
  21. package/lib/build/provider/hana/2migration.js +6 -6
  22. package/lib/build/provider/nodejs/index.js +5 -4
  23. package/lib/build/util.js +2 -1
  24. package/lib/compile/to-mermaid.js +4 -6
  25. package/lib/import/common.js +16 -18
  26. package/lib/import/message.js +6 -5
  27. package/lib/import/odata/index.js +1 -1
  28. package/lib/import/odata/v2parser.js +18 -17
  29. package/lib/import/odata/v4parser.js +62 -62
  30. package/lib/init/constants.js +3 -2
  31. package/lib/init/mvn.js +43 -6
  32. package/lib/init/plugin.js +1 -1
  33. package/lib/init/projectReader.js +1 -1
  34. package/lib/init/template/approuter/files/containerize.yaml.hbs +5 -0
  35. package/lib/init/template/cloud-logging/files/mta.yaml.hbs +25 -0
  36. package/lib/init/template/cloud-logging/files/package.json +14 -0
  37. package/lib/init/template/cloud-logging/index.js +80 -0
  38. package/lib/init/template/containerize/files/containerize.yaml.hbs +5 -0
  39. package/lib/init/template/dynatrace/files/mta.yaml.hbs +24 -0
  40. package/lib/init/template/dynatrace/files/package.json.hbs +14 -0
  41. package/lib/init/template/dynatrace/files/sidecar.package.json +0 -0
  42. package/lib/init/template/dynatrace/index.js +55 -0
  43. package/lib/init/template/hana/files/containerize.yaml.hbs +5 -0
  44. package/lib/init/template/hana/files/package.json.hbs +5 -3
  45. package/lib/init/template/handler/index.js +22 -0
  46. package/lib/init/template/helm/index.js +5 -1
  47. package/lib/init/template/html5-repo/index.js +5 -0
  48. package/lib/init/template/http/index.js +1 -1
  49. package/lib/init/template/java/index.js +2 -2
  50. package/lib/init/template/multitenancy/files/containerize.yaml.hbs +5 -0
  51. package/lib/init/template/portal/files/portal-site/CommonDataModel.json.hbs +2 -2
  52. package/lib/init/template/portal/files/values.yaml.hbs +43 -0
  53. package/lib/init/template/portal/index.js +4 -2
  54. package/lib/init/template/telemetry/index.js +19 -0
  55. package/lib/init/template/typescript/files/package.json +1 -3
  56. package/lib/mtx/auth_manager.js +12 -15
  57. package/lib/mtx/settings_manager.js +5 -2
  58. package/lib/mtx/util/logging.js +4 -4
  59. package/lib/util/cf.js +15 -5
  60. package/lib/util/command.js +3 -3
  61. package/lib/watch/livereload-server.js +3 -3
  62. package/lib/watch/node-watch.js +3 -3
  63. package/npm-shrinkwrap.json +32 -23
  64. package/package.json +3 -2
  65. package/readme.md +2 -2
@@ -61,7 +61,7 @@ async function edmx2csn(edmx, filename, context) {
61
61
  namespace = (index > 0) ? result[1].substring(0, index) : result[1];
62
62
  }
63
63
  else {
64
- // to support edmx without entities - unbounded actions and functions only
64
+ // to support edmx without entities - unbound actions and functions only
65
65
  console.warn('There are no entities in the OData model');
66
66
  let schema = edmx.match(/(<Schema [^>]*>)/);
67
67
  if (!schema) throw new Error(messages.INVALID_EDMX_METADATA);
@@ -303,21 +303,21 @@ function _getFunctionAttributes(functionImport, serviceNamespaceParam) {
303
303
  }
304
304
 
305
305
  function _extractFunctionImport(functionImport, parserContext) {
306
- //extracting the bounded and unbounded function import
307
- let boundedFunctionImports = [];
306
+ //extracting the bound and unbound function import
307
+ let boundFunctionImports = [];
308
308
  let entityName;
309
309
  Object.keys(functionImport).forEach((key) => {
310
310
  if (key === "_attributes") {
311
311
  if (functionImport[key]["sap:action-for"]) {
312
- //storing bounded function imports
312
+ //storing bound function imports
313
313
  entityName = _extractEntityFromNamespace(functionImport[key]["sap:action-for"]);
314
- boundedFunctionImports = (parserContext.allFunctionImportsMap[entityName])
314
+ boundFunctionImports = (parserContext.allFunctionImportsMap[entityName])
315
315
  ? parserContext.allFunctionImportsMap[entityName] : [];
316
- boundedFunctionImports.push(_getFunctionAttributes(functionImport, ""));
317
- parserContext.allFunctionImportsMap[entityName] = boundedFunctionImports;
316
+ boundFunctionImports.push(_getFunctionAttributes(functionImport, ""));
317
+ parserContext.allFunctionImportsMap[entityName] = boundFunctionImports;
318
318
  }
319
319
  else {
320
- //storing unbounded function imports
320
+ //storing unbound function imports
321
321
  parserContext.allFunctionImports.push(
322
322
  _getFunctionAttributes(functionImport, parserContext.serviceNamespace + ".")
323
323
  );
@@ -786,7 +786,7 @@ function _parseParametersFunctionImport(parameters, entityKeysList, parserContex
786
786
  return csn;
787
787
  }
788
788
 
789
- function _getFunctionImport(functionImport, isBounded, entityKeysList, parserContext) {
789
+ function _getFunctionImport(functionImport, isBound, entityKeysList, parserContext) {
790
790
  let noValue;
791
791
  let csn = "";
792
792
  csn = csn + '"' + functionImport[0] + '": { \n';
@@ -803,10 +803,10 @@ function _getFunctionImport(functionImport, isBounded, entityKeysList, parserCon
803
803
  return "";
804
804
  }
805
805
  csn = csn + '"';
806
- if (!isBounded) csn = csn + ',\n"@cds.external": true';
806
+ if (!isBound) csn = csn + ',\n"@cds.external": true';
807
807
 
808
808
  if (functionImport[3] !== -1) {
809
- if (isBounded === 0 || (isBounded === 1 && functionImport[3] instanceof Array)) {
809
+ if (isBound === 0 || (isBound === 1 && functionImport[3] instanceof Array)) {
810
810
  let parametersCsn = _parseParametersFunctionImport(functionImport[3], entityKeysList, parserContext);
811
811
  if (parametersCsn != "") {
812
812
  csn = csn + ", \n";
@@ -846,12 +846,12 @@ function _getFunctionImport(functionImport, isBounded, entityKeysList, parserCon
846
846
  return csn;
847
847
  }
848
848
 
849
- function _getAllFunctionImports(functionImports, isBounded, entityKeysList, parserContext) {
849
+ function _getAllFunctionImports(functionImports, isBound, entityKeysList, parserContext) {
850
850
  let functionImportsCSN = "";
851
851
  let i;
852
852
  let functionImportCSN = "";
853
853
  for (i = 0; i < functionImports.length; i++) {
854
- functionImportCSN = _getFunctionImport(functionImports[i], isBounded, entityKeysList, parserContext);
854
+ functionImportCSN = _getFunctionImport(functionImports[i], isBound, entityKeysList, parserContext);
855
855
  functionImportsCSN = functionImportsCSN + functionImportCSN;
856
856
  if (i !== functionImports.length - 1 && functionImportCSN !== "") {
857
857
  functionImportsCSN = functionImportsCSN + ",\n";
@@ -1439,7 +1439,7 @@ function _constructServiceEntity(
1439
1439
  }
1440
1440
  }
1441
1441
 
1442
- // if the function import is bounded to entitySet
1442
+ // if the function import is bound to entitySet
1443
1443
  if (parserContext.allFunctionImportsMap[entityName]) {
1444
1444
  csnEntity = csnEntity + ', \n "actions": {\n';
1445
1445
  csnEntity = csnEntity +
@@ -1448,7 +1448,7 @@ function _constructServiceEntity(
1448
1448
  );
1449
1449
  csnEntity = csnEntity + "}";
1450
1450
  }
1451
- // if the function import is bounded to entityType
1451
+ // if the function import is bound to entityType
1452
1452
  else if (parserContext.allFunctionImportsMap[_extractEntityFromNamespace(parserContext.allEntitySetMap[entityName])]) {
1453
1453
  csnEntity = csnEntity + ', \n "actions": {\n';
1454
1454
  csnEntity = csnEntity +
@@ -1650,7 +1650,8 @@ function _generateEDMXJSON2CSN(jsonObj, ignorePersistenceSkip, parserContext) {
1650
1650
  }
1651
1651
 
1652
1652
  // Construct CSN entity based on EDMX entity
1653
- const entityJson = jsonObj["edmx:Edmx"]["edmx:DataServices"].Schema.EntityType;
1653
+ let entityJson = jsonObj["edmx:Edmx"]["edmx:DataServices"].Schema.EntityType;
1654
+ if (!Array.isArray(entityJson)) entityJson = [entityJson];
1654
1655
  const definitions = [];
1655
1656
 
1656
1657
  if (parserContext.mockServerUc) {
@@ -1695,9 +1696,9 @@ function _generateEDMXJSON2CSN(jsonObj, ignorePersistenceSkip, parserContext) {
1695
1696
  definitions.push(_getServiceComplexTypes(parserContext));
1696
1697
  }
1697
1698
 
1698
- // if there are unbounded function imports
1699
+ // if there are unbound function imports
1699
1700
  if (Object.keys(parserContext.allFunctionImports).length > 0) {
1700
- // passing 0 for unbounded actions/functions and 0 for entityKeysList
1701
+ // passing 0 for unbound actions/functions and 0 for entityKeysList
1701
1702
  definitions.push(
1702
1703
  _getAllFunctionImports(parserContext.allFunctionImports, 0, 0, parserContext)
1703
1704
  );
@@ -83,8 +83,8 @@ const known_vocabularies = {
83
83
  };
84
84
 
85
85
  function _initialize(parserContext) {
86
- parserContext.unboundedActions = {};
87
- parserContext.unboundedFunctions = {};
86
+ parserContext.unboundActions = {};
87
+ parserContext.unboundFunctions = {};
88
88
  parserContext.entityTypes = [];
89
89
  parserContext.entityTypeOpenEntries = [];
90
90
  parserContext.complexTypeOpenEntries = [];
@@ -100,8 +100,8 @@ function _initialize(parserContext) {
100
100
  parserContext.schemaAliasToNamespace = {};
101
101
  parserContext.schemaToSchemaDataIndex = {};
102
102
  parserContext.vocabNamespaceToAlias = {};
103
- parserContext.entityToBoundedActions = {};
104
- parserContext.entityToBoundedFunctions = {};
103
+ parserContext.entityToBoundActions = {};
104
+ parserContext.entityToBoundFunctions = {};
105
105
  parserContext.entityContainerAnnotations = {};
106
106
  parserContext.mockServerUc = true;
107
107
  parserContext.beta = false;
@@ -911,9 +911,9 @@ function _parseParameterAndReturnTypeContent(elementObject, parserContext) {
911
911
  }
912
912
  }
913
913
 
914
- function _generateCSNForBoundedActionFunction(actionFunctionObject, kind, parserContext) {
914
+ function _generateCSNForBoundActionFunction(actionFunctionObject, kind, parserContext) {
915
915
  const csnObj = {};
916
- const isBounded = actionFunctionObject.$IsBound;
916
+ const isBound = actionFunctionObject.$IsBound;
917
917
  const parameters = actionFunctionObject.$Parameter;
918
918
  const returnType = actionFunctionObject.$ReturnType;
919
919
 
@@ -932,7 +932,7 @@ function _generateCSNForBoundedActionFunction(actionFunctionObject, kind, parser
932
932
  * NOTE: Edm.Stream can act as the binding parameter for action/function
933
933
  * We don't have any example for it, so not handled as of now
934
934
  */
935
- if (isBounded && index === 0) {
935
+ if (isBound && index === 0) {
936
936
  if (isCollection) {
937
937
  csnObj.params[parameters[index].$Name].items.type = '$self';
938
938
  }
@@ -949,20 +949,20 @@ function _generateCSNForBoundedActionFunction(actionFunctionObject, kind, parser
949
949
  return csnObj;
950
950
  }
951
951
 
952
- function _parseBoundedActionFunction(schemaData, csnObj, kind, parserContext) {
953
- const boundedObject = (kind === 'action') ? parserContext.entityToBoundedActions : parserContext.entityToBoundedFunctions;
952
+ function _parseBoundActionFunction(schemaData, csnObj, kind, parserContext) {
953
+ const boundObject = (kind === 'action') ? parserContext.entityToBoundActions : parserContext.entityToBoundFunctions;
954
954
 
955
- Object.keys(boundedObject).forEach(fqEntityName => {
955
+ Object.keys(boundObject).forEach(fqEntityName => {
956
956
  const [schemaName, ] = _extractSchemaNameAndElementName(fqEntityName);
957
957
 
958
958
  if (schemaName === schemaData.$SchemaNamespace) {
959
- const actionFunctionObjectList = boundedObject[fqEntityName];
959
+ const actionFunctionObjectList = boundObject[fqEntityName];
960
960
 
961
961
  if (!csnObj[fqEntityName].actions) {
962
962
  csnObj[fqEntityName].actions = {};
963
963
  }
964
964
  Object.keys(actionFunctionObjectList).forEach(actionFunctionName => {
965
- csnObj[fqEntityName].actions[actionFunctionName] = _generateCSNForBoundedActionFunction(
965
+ csnObj[fqEntityName].actions[actionFunctionName] = _generateCSNForBoundActionFunction(
966
966
  actionFunctionObjectList[actionFunctionName], kind, parserContext
967
967
  );
968
968
  });
@@ -970,15 +970,15 @@ function _parseBoundedActionFunction(schemaData, csnObj, kind, parserContext) {
970
970
  });
971
971
  }
972
972
 
973
- function _parseUnBoundedActionFunction(schemaData, kind, parserContext) {
974
- const unBoundedObject = (kind === 'action') ? parserContext.unboundedActions : parserContext.unboundedFunctions;
973
+ function _parseUnboundActionFunction(schemaData, kind, parserContext) {
974
+ const unboundObject = (kind === 'action') ? parserContext.unboundActions : parserContext.unboundFunctions;
975
975
  const csnObj = {};
976
976
 
977
- Object.keys(unBoundedObject).forEach(fqName => {
977
+ Object.keys(unboundObject).forEach(fqName => {
978
978
  const [schemaName, ] = _extractSchemaNameAndElementName(fqName);
979
979
 
980
980
  if (schemaName === schemaData.$SchemaNamespace) {
981
- const actionFunctionObject = unBoundedObject[fqName];
981
+ const actionFunctionObject = unboundObject[fqName];
982
982
  const parameters = actionFunctionObject.$Parameter;
983
983
  const returnType = actionFunctionObject.$ReturnType;
984
984
 
@@ -1129,7 +1129,7 @@ function _resolveActionFunctionAnnotationTarget(targetPath, csnDefs, hasParamete
1129
1129
  const fqActFunName = _resolveAliasedElementName(elemNameList[0], parserContext);
1130
1130
  const paramName = hasParameter ? targetPath.split('/')[1] : null;
1131
1131
 
1132
- // unbounded action or function
1132
+ // unbound action or function
1133
1133
  if (csnDefs[fqActFunName]) {
1134
1134
  // with parameter
1135
1135
  if (hasParameter && csnDefs[fqActFunName].params[paramName]) {
@@ -1140,7 +1140,7 @@ function _resolveActionFunctionAnnotationTarget(targetPath, csnDefs, hasParamete
1140
1140
  return csnDefs[fqActFunName];
1141
1141
  }
1142
1142
  }
1143
- // bounded action or function
1143
+ // bound action or function
1144
1144
  else {
1145
1145
  const [, elementName] = _extractSchemaNameAndElementName(fqActFunName);
1146
1146
  const isCollection = elemNameList[1] === 'Collection' ? true : false;
@@ -1388,10 +1388,10 @@ function _collectAllParameters(dataObjList) {
1388
1388
  * @param {Object} parserContext
1389
1389
  *
1390
1390
  * Scenarios:
1391
- * 1. UnBounded Actions can't have collision. Action name must be unique.
1392
- * 2. UnBounded Functions can have collision; capture the max number of parameters.
1391
+ * 1. Unbound Actions can't have collision. Action name must be unique.
1392
+ * 2. Unbound Functions can have collision; capture the max number of parameters.
1393
1393
  */
1394
- function _populateUnboundedActionFunction(isAction, fqName, schemaDataList, parserContext) {
1394
+ function _populateUnboundActionFunction(isAction, fqName, schemaDataList, parserContext) {
1395
1395
  let [schemaName, actFunName] = _extractSchemaNameAndElementName(fqName);
1396
1396
  let indexOfSchema;
1397
1397
  [indexOfSchema, schemaName] = _getIndexAndNamespaceOfSchema(fqName, schemaName, parserContext);
@@ -1401,33 +1401,33 @@ function _populateUnboundedActionFunction(isAction, fqName, schemaDataList, pars
1401
1401
 
1402
1402
  if (isAction) {
1403
1403
  if (dataList.length === 1) {
1404
- parserContext.unboundedActions[fqName] = actionFunctionObject;
1404
+ parserContext.unboundActions[fqName] = actionFunctionObject;
1405
1405
  }
1406
1406
  else {
1407
- throw new Error(messages.UNBOUNDED_ACTION_COLLISION + `'${actFunName}' of Schema: ${schemaName} `);
1407
+ throw new Error(messages.UNBOUND_ACTION_COLLISION + `'${actFunName}' of Schema: ${schemaName} `);
1408
1408
  }
1409
1409
  }
1410
1410
  else {
1411
1411
  if (dataList.length > 1) {
1412
1412
  actionFunctionObject['$Parameter'] = _collectAllParameters(dataList);
1413
- parserContext.unboundedFunctions[fqName] = actionFunctionObject;
1413
+ parserContext.unboundFunctions[fqName] = actionFunctionObject;
1414
1414
  }
1415
1415
  else {
1416
- parserContext.unboundedFunctions[fqName] = actionFunctionObject;
1416
+ parserContext.unboundFunctions[fqName] = actionFunctionObject;
1417
1417
  }
1418
1418
  // throw error if the return type is missing
1419
- if (!parserContext.unboundedFunctions[fqName].$ReturnType) {
1419
+ if (!parserContext.unboundFunctions[fqName].$ReturnType) {
1420
1420
  throw new Error(messages.NO_RETURN_TYPE + actFunName);
1421
1421
  }
1422
1422
  }
1423
1423
  }
1424
1424
 
1425
- function _collectUnboundedActionFunction(schemaDataList, parserContext) {
1425
+ function _collectUnboundActionFunction(schemaDataList, parserContext) {
1426
1426
  for (let actionName of parserContext.actionToActionImportMap.keys()) {
1427
- _populateUnboundedActionFunction(true, actionName, schemaDataList, parserContext);
1427
+ _populateUnboundActionFunction(true, actionName, schemaDataList, parserContext);
1428
1428
  }
1429
1429
  for (let functionName of parserContext.functionToFunctionImportMap.keys()) {
1430
- _populateUnboundedActionFunction(false, functionName, schemaDataList, parserContext);
1430
+ _populateUnboundActionFunction(false, functionName, schemaDataList, parserContext);
1431
1431
  }
1432
1432
  }
1433
1433
 
@@ -1435,22 +1435,22 @@ function _collectUnboundedActionFunction(schemaDataList, parserContext) {
1435
1435
  * @param {Boolean} isAction
1436
1436
  * @param {String} currNamespace
1437
1437
  * @param {String} elementName
1438
- * @param {List<Object>} elementDataList, bounded action/function details
1438
+ * @param {List<Object>} elementDataList, bound action/function details
1439
1439
  * @param {Object} parserContext
1440
1440
  *
1441
- * Scenarios for bounded actions, functions:
1441
+ * Scenarios for bound actions, functions:
1442
1442
  * 1. Actions with same name and binding parameter type can't have collision.
1443
1443
  * 2. Functions can have collision and we will capture the max number of parameters.
1444
- * Special scenario is when same function name is bounded to different entity as well.
1444
+ * Special scenario is when same function name is bound to different entity as well.
1445
1445
  */
1446
- function _collectBoundedActionFunction(isAction, currNamespace, elementName, elementDataList, parserContext) {
1446
+ function _collectBoundActionFunction(isAction, currNamespace, elementName, elementDataList, parserContext) {
1447
1447
  let functionObjList; // list to collect all the collision obj for function
1448
1448
 
1449
1449
  for (let i = 0; i < elementDataList.length; i++) {
1450
1450
  let dataObj = elementDataList[i];
1451
- let boundedEntityName = dataObj.$Parameter[0].$Type;
1451
+ let boundEntityName = dataObj.$Parameter[0].$Type;
1452
1452
  let entityTypeNamespace = currNamespace;
1453
- let [schemaName, entityName] = _extractSchemaNameAndElementName(boundedEntityName);
1453
+ let [schemaName, entityName] = _extractSchemaNameAndElementName(boundEntityName);
1454
1454
 
1455
1455
  // binding parameter type should be within the available namespaces in the scope of a document.
1456
1456
  if (entityTypeNamespace !== schemaName && entityTypeNamespace !== parserContext.schemaAliasToNamespace[schemaName]) {
@@ -1463,35 +1463,35 @@ function _collectBoundedActionFunction(isAction, currNamespace, elementName, ele
1463
1463
  else if (parserContext.schemaAliasToNamespace[schemaName]) {
1464
1464
  entityTypeNamespace = parserContext.schemaAliasToNamespace[schemaName];
1465
1465
  } else {
1466
- throw new Error(messages.INVALID_BOUNDED_PARAM_TYPE + ` Check the Element: ${elementName} of Schema: ${currNamespace} `);
1466
+ throw new Error(messages.INVALID_BOUND_PARAM_TYPE + ` Check the Element: ${elementName} of Schema: ${currNamespace} `);
1467
1467
  }
1468
1468
  }
1469
1469
 
1470
1470
  if (!parserContext.entityTypes.includes(entityTypeNamespace + '.' + entityName)) {
1471
- throw new Error(messages.UNRESOLVED_TYPE + boundedEntityName);
1471
+ throw new Error(messages.UNRESOLVED_TYPE + boundEntityName);
1472
1472
  }
1473
- boundedEntityName = entityTypeNamespace + '.' + entityName;
1473
+ boundEntityName = entityTypeNamespace + '.' + entityName;
1474
1474
 
1475
1475
  if (isAction) {
1476
- if (!parserContext.entityToBoundedActions[boundedEntityName]?.[elementName]) {
1477
- if (!parserContext.entityToBoundedActions[boundedEntityName]) {
1478
- parserContext.entityToBoundedActions[boundedEntityName] = {};
1476
+ if (!parserContext.entityToBoundActions[boundEntityName]?.[elementName]) {
1477
+ if (!parserContext.entityToBoundActions[boundEntityName]) {
1478
+ parserContext.entityToBoundActions[boundEntityName] = {};
1479
1479
  }
1480
- parserContext.entityToBoundedActions[boundedEntityName][elementName] = dataObj;
1480
+ parserContext.entityToBoundActions[boundEntityName][elementName] = dataObj;
1481
1481
  }
1482
1482
  else {
1483
- throw new Error(messages.BOUNDED_ACTION_COLLISION + ` Check the Element: ${elementName} of Schema: ${currNamespace} `);
1483
+ throw new Error(messages.BOUND_ACTION_COLLISION + `${elementName} in entity ${entityName} of schema ${currNamespace}.`);
1484
1484
  }
1485
1485
  }
1486
1486
  else {
1487
- if (!parserContext.entityToBoundedFunctions[boundedEntityName]?.[elementName]) {
1488
- if (!parserContext.entityToBoundedFunctions[boundedEntityName]) {
1489
- parserContext.entityToBoundedFunctions[boundedEntityName] = {};
1487
+ if (!parserContext.entityToBoundFunctions[boundEntityName]?.[elementName]) {
1488
+ if (!parserContext.entityToBoundFunctions[boundEntityName]) {
1489
+ parserContext.entityToBoundFunctions[boundEntityName] = {};
1490
1490
  }
1491
- if (!functionObjList || !parserContext.entityToBoundedFunctions[boundedEntityName][elementName]) {
1491
+ if (!functionObjList || !parserContext.entityToBoundFunctions[boundEntityName][elementName]) {
1492
1492
  functionObjList = [];
1493
1493
  }
1494
- parserContext.entityToBoundedFunctions[boundedEntityName][elementName] = dataObj;
1494
+ parserContext.entityToBoundFunctions[boundEntityName][elementName] = dataObj;
1495
1495
  functionObjList.push(dataObj);
1496
1496
  }
1497
1497
  else {
@@ -1499,10 +1499,10 @@ function _collectBoundedActionFunction(isAction, currNamespace, elementName, ele
1499
1499
  let functionObject = functionObjList[0];
1500
1500
  functionObject['$Parameter'] = _collectAllParameters(functionObjList);
1501
1501
  functionObjList = [functionObject]; // reset the function object list with recently formed object
1502
- parserContext.entityToBoundedFunctions[boundedEntityName][elementName] = functionObject;
1502
+ parserContext.entityToBoundFunctions[boundEntityName][elementName] = functionObject;
1503
1503
  }
1504
1504
  // throw error if the return type is missing
1505
- if (!parserContext.entityToBoundedFunctions[boundedEntityName][elementName].$ReturnType) {
1505
+ if (!parserContext.entityToBoundFunctions[boundEntityName][elementName].$ReturnType) {
1506
1506
  throw new Error(messages.NO_RETURN_TYPE + elementName);
1507
1507
  }
1508
1508
  }
@@ -1515,10 +1515,10 @@ function _collectBoundedActionFunction(isAction, currNamespace, elementName, ele
1515
1515
  * @param {Object} parserContext, contains parser level context informations
1516
1516
  */
1517
1517
  function _collectSchemaElements(edmxAsJson, schemaDataList, parserContext) {
1518
- // This array is used to store the parameter values which will be used later to call _collectBoundedActionFunction.
1518
+ // This array is used to store the parameter values which will be used later to call _collectBoundActionFunction.
1519
1519
  let boundActionFunctionDetails = [];
1520
1520
 
1521
- _collectUnboundedActionFunction(schemaDataList, parserContext);
1521
+ _collectUnboundActionFunction(schemaDataList, parserContext);
1522
1522
 
1523
1523
  // capture all the references
1524
1524
  if (edmxAsJson.$Reference) {
@@ -1527,7 +1527,7 @@ function _collectSchemaElements(edmxAsJson, schemaDataList, parserContext) {
1527
1527
  });
1528
1528
  }
1529
1529
 
1530
- // collect entityType, enumType, complexType, typeDefinition, bounded action/function, annotations
1530
+ // collect entityType, enumType, complexType, typeDefinition, bound action/function, annotations
1531
1531
  for (let schemaData of schemaDataList) {
1532
1532
  let currNamespace = schemaData.$SchemaNamespace;
1533
1533
 
@@ -1540,7 +1540,7 @@ function _collectSchemaElements(edmxAsJson, schemaDataList, parserContext) {
1540
1540
  else if (elementData.$Kind === 'EnumType') parserContext.enumTypes.push(fqName);
1541
1541
  else if (elementData.$Kind === 'ComplexType') parserContext.complexTypes.push(fqName);
1542
1542
  else if (elementData.$Kind === 'TypeDefinition') parserContext.typeDefinitions.push(fqName);
1543
- // bounded actions/functions
1543
+ // bound actions/functions
1544
1544
  else if (elementData instanceof Array) {
1545
1545
  let isAction = elementData[0].$Kind === 'Action' ? true : false;
1546
1546
  if (elementData[0].$IsBound) {
@@ -1570,9 +1570,9 @@ function _collectSchemaElements(edmxAsJson, schemaDataList, parserContext) {
1570
1570
  }
1571
1571
  });
1572
1572
  }
1573
- // This will delay the execution of _collectBoundedActionFunction, as we need to collect all the entityTypes first.
1573
+ // This will delay the execution of _collectBoundActionFunction, as we need to collect all the entityTypes first.
1574
1574
  boundActionFunctionDetails.forEach(paramValues => {
1575
- _collectBoundedActionFunction(...paramValues, parserContext);
1575
+ _collectBoundActionFunction(...paramValues, parserContext);
1576
1576
  });
1577
1577
  }
1578
1578
 
@@ -1651,12 +1651,12 @@ function _generateCSN(edmxAsJson, ignorePersistenceSkip, parserContext, importer
1651
1651
  csn.definitions = Object.assign(_parserCSNForComplexType(schemaData, parserContext), csn.definitions);
1652
1652
  // Step 4: parse all entity type
1653
1653
  csn.definitions = Object.assign(_parseCSNForEntityType(schemaData, ignorePersistenceSkip, parserContext), csn.definitions);
1654
- // Step 5: parse all bounded action & function
1655
- _parseBoundedActionFunction(schemaData, csn.definitions, 'action', parserContext);
1656
- _parseBoundedActionFunction(schemaData, csn.definitions, 'function', parserContext);
1657
- // Step 6: parse all unbounded action & function
1658
- csn.definitions = Object.assign(_parseUnBoundedActionFunction(schemaData, 'action', parserContext), csn.definitions);
1659
- csn.definitions = Object.assign(_parseUnBoundedActionFunction(schemaData, 'function', parserContext), csn.definitions);
1654
+ // Step 5: parse all bound action & function
1655
+ _parseBoundActionFunction(schemaData, csn.definitions, 'action', parserContext);
1656
+ _parseBoundActionFunction(schemaData, csn.definitions, 'function', parserContext);
1657
+ // Step 6: parse all unbound action & function
1658
+ csn.definitions = Object.assign(_parseUnboundActionFunction(schemaData, 'action', parserContext), csn.definitions);
1659
+ csn.definitions = Object.assign(_parseUnboundActionFunction(schemaData, 'function', parserContext), csn.definitions);
1660
1660
  // Step 7: parse all annotations
1661
1661
  if (schemaData.$Annotations) {
1662
1662
  _parseAnnotations(schemaData.$Annotations, csn.definitions, parserContext);
@@ -5,7 +5,7 @@ module.exports = {
5
5
  COMMAND_ADD: 'add',
6
6
 
7
7
  JAVA_LTS_VERSIONS: [17, 21],
8
- MAVEN_ARCHETYPE_VERSION: '3.1.1',
8
+ MAVEN_ARCHETYPE_VERSION: '3.2.0',
9
9
 
10
10
  OPTIONS: Object.freeze({
11
11
  COMPLETION: 'completion',
@@ -72,7 +72,8 @@ module.exports = {
72
72
  MAVEN_INSTALL_HELP: `https://maven.apache.org/install.html`,
73
73
  CAP_JS_COMMUNITY_ODATA_V2: 'https://github.com/cap-js-community/odata-v2-adapter',
74
74
  CAP_JS_COMMUNITY_EVENT_QUEUE: 'https://github.com/cap-js-community/event-queue',
75
- CAP_JS_COMMUNITY_WEBSOCKET: 'https://github.com/cap-js-community/websocket'
75
+ CAP_JS_COMMUNITY_WEBSOCKET: 'https://github.com/cap-js-community/websocket',
76
+ CF_CLI: 'https://github.com/cloudfoundry/cli'
76
77
  }),
77
78
 
78
79
  PROJECT_FILES: ['package.json', 'pom.xml', '.cdsrc.json']
package/lib/init/mvn.js CHANGED
@@ -1,4 +1,5 @@
1
1
  const util = require('util')
2
+ const path = require('path');
2
3
  const { exec } = require('child_process')
3
4
  const execAsync = util.promisify(exec)
4
5
 
@@ -6,7 +7,7 @@ const term = require('../util/term')
6
7
  const cmd = require('../util/command')
7
8
 
8
9
  const cds = require('../cds')
9
- const DEBUG = cds.debug('cli|init|add|mvn')
10
+ const LOG = cds.log('cli|init|add|mvn'), DEBUG = cds.debug('cli|init|add|mvn')
10
11
 
11
12
  const { URLS, MAVEN_ARCHETYPE_VERSION, OPTIONS: { JAVA_PACKAGE, HANA }, REGEX_JAVA_PACKAGE } = require('./constants')
12
13
 
@@ -16,9 +17,9 @@ module.exports.add = async function (feature) {
16
17
  const { 'java:mvn': javaMvn, force } = cds.cli.options
17
18
  if (javaMvn) _scan(javaMvn).forEach(([k,v]) => params.set(k,v))
18
19
  const archetypeVersion = params.get('-DarchetypeVersion') ?? MAVEN_ARCHETYPE_VERSION
19
- if (feature === HANA) { // REVISIT: compat for HANA when -Dfeature HANA is provided by Java
20
+ if (feature === HANA) { // REVISIT: compat for HANA until -Dfeature HANA is provided by Java
20
21
  params.set(`com.sap.cds:cds-maven-plugin:${archetypeVersion}:addTargetPlatform`)
21
- params.set(`-DtargetPlatform`, `cloudfoundry`) // REVISIT: No special handling for HANA
22
+ params.set(`-DtargetPlatform`, `cloudfoundry`) // REVISIT: Should get rid of CF dependency for Kyma scenarios
22
23
  } else {
23
24
  params.set(`com.sap.cds:cds-maven-plugin:${archetypeVersion}:add`)
24
25
  params.set(`-Dfeature`, feature)
@@ -46,6 +47,7 @@ module.exports.init = async function (projectName, options = cds.cli.options) {
46
47
  params.set(`-DarchetypeGroupId`, `com.sap.cds`);
47
48
  params.set(`-DarchetypeVersion`, MAVEN_ARCHETYPE_VERSION);
48
49
  params.set('-DinteractiveMode', false);
50
+ if (cds.cli.options['no-db']) params.set('-Dpersistence', false)
49
51
 
50
52
  // set defaults, might be changed by java:mvn param
51
53
  params.set(`-DartifactId`, projectName);
@@ -101,6 +103,41 @@ module.exports.init = async function (projectName, options = cds.cli.options) {
101
103
  return { params: _finalize(params), archetypeVersion, artifactId }
102
104
  }
103
105
 
106
+ module.exports.generate = async function (feature, options = cds.cli.options) {
107
+ const command = this.generateMvnParams(feature, options)
108
+ const cwd = options.cwd
109
+
110
+ try {
111
+ console.log(`Executing command: `, term.highlight('mvn ' + command.join(' ')))
112
+ await cmd.spawnCommand('mvn', command, { cwd: cwd ?? path.join(cds.root, 'srv') })
113
+ return command
114
+ } catch (err) {
115
+ if (err.code === 'ENOENT' && err.path === 'mvn') {
116
+ throw `Maven executable 'mvn' not found. Follow ${term.info(URLS.MAVEN_INSTALL_HELP)} and install Maven on your machine.`
117
+ }
118
+ throw err
119
+ }
120
+ }
121
+
122
+ module.exports.generateMvnParams = function (feature, options = cds.cli.options) {
123
+ const params = new Map()
124
+
125
+ const { 'java:mvn': javaMvn, force, filter, out } = options
126
+ if (javaMvn) _scan(javaMvn).forEach(([k,v]) => params.set(k,v))
127
+ const archVersion = params.get(`-DarchetypeVersion`) ?? ''
128
+ params.set(`cds:${archVersion}:generate`)
129
+
130
+ switch (feature) {
131
+ case 'handler':
132
+ params.set(`-Dcds.generate.feature=EVENT_HANDLERS`)
133
+ break
134
+ }
135
+ if (filter) params.set(`-Dcds.generate.includes=**.${filter.replace(/\*+\.?/, '')}**`)
136
+ if (out) params.set(`-Dcds.generate.handlers.package=${out.replaceAll('/', '.')}`)
137
+ if (force) params.set(`-Dcds.generate.overwrite`, true)
138
+ return _finalize(params)
139
+ }
140
+
104
141
  const sanitize = module.exports.sanitize = name => name
105
142
  .toLowerCase()
106
143
  .replace(/-/g, '_')
@@ -123,10 +160,10 @@ function _scan(mvnParams) {
123
160
 
124
161
  function _finalize(params) {
125
162
  params.set(`-Dstyle.color`, `always`)
126
- if (DEBUG) params.set('-X')
127
- if (DEBUG) params.set('-e')
163
+ if (LOG._debug) params.set('-X')
164
+ if (LOG._debug) params.set('-e')
128
165
  if (process.env.CI) params.set('--batch-mode')
129
166
  const final = Array.from(params, ([arg, val]) => val !== null && val !== undefined ? `${arg}=${val}` : arg)
130
- DEBUG?.(term.highlight('mvn' + final.join(' ')))
167
+ DEBUG?.(term.highlight('mvn ' + final.join(' ')))
131
168
  return final
132
169
  }
@@ -1,7 +1,6 @@
1
1
  const { join } = require('path')
2
2
  const cds = require('../cds')
3
3
  const { readdir } = cds.utils
4
- const DEBUG = cds.debug('cli|add')
5
4
 
6
5
  module.exports = class Plugin {
7
6
 
@@ -68,6 +67,7 @@ module.exports = class Plugin {
68
67
  –––––––––––– */
69
68
 
70
69
  async combineSupported() {
70
+ const DEBUG = cds.log('cli|add')._debug
71
71
  DEBUG && console.log()
72
72
  DEBUG && console.log('Plugins active for production:')
73
73
  const fromDk = await readdir(join(__dirname, './template'))
@@ -145,7 +145,7 @@ module.exports = new class ProjectReader {
145
145
  const inbounds = manifest?.['sap.app']?.crossNavigation?.inbounds
146
146
  const [firstInbound] = Object.values(inbounds ?? { intent: { semanticObject: 'Books', action: 'display' }})
147
147
  const vizId = firstInbound.semanticObject + '-' + firstInbound.action
148
- return { app, strippedApp: app.replace(/-/g, ''), vizId, isNotLast: i < apps.length - 1 }
148
+ return { app, strippedApp: app.replace(/-/g, ''), vizId, isNotLast: i < apps.length - 1, manifestAppId: manifest?.['sap.app']?.id ?? app}
149
149
  })
150
150
  },
151
151
  appUIPaths: () => (fs.readdirSync(path.resolve(cds.root, cds.env.folders.app))).filter(e =>
@@ -3,8 +3,13 @@ modules:
3
3
  - name: {{appName}}-approuter
4
4
  build-parameters:
5
5
  buildpack:
6
+ {{#hasHelmUnifiedRuntime}}
7
+ builder: proxy-unified-runtime-dmz.int.repositories.cloud.sap/builder/noble
8
+ {{/hasHelmUnifiedRuntime}}
9
+ {{^hasHelmUnifiedRuntime}}
6
10
  type: nodejs
7
11
  builder: builder-jammy-base
12
+ {{/hasHelmUnifiedRuntime}}
8
13
  path: app/router
9
14
  env:
10
15
  BP_NODE_RUN_SCRIPTS: ""
@@ -0,0 +1,25 @@
1
+ ---
2
+ modules:
3
+ - name: {{appName}}-srv
4
+ type: {{language}}
5
+ path: {{& srvPath}}
6
+ requires:
7
+ - name: {{appName}}-cloud-logging
8
+ - name: {{appName}}-mtx
9
+ type: nodejs
10
+ path: {{#isNodejs}}gen/{{/isNodejs}}mtx/sidecar
11
+ requires:
12
+ - name: {{appName}}-cloud-logging
13
+ - name: {{appName}}
14
+ type: approuter.nodejs
15
+ requires:
16
+ - name: {{appName}}-cloud-logging
17
+ resources:
18
+ - name: {{appName}}-cloud-logging
19
+ type: org.cloudfoundry.managed-service
20
+ parameters:
21
+ service: cloud-logging
22
+ service-plan: {{cloudLoggingServicePlan}}
23
+ config:
24
+ ingest_otlp:
25
+ enabled: true
@@ -0,0 +1,14 @@
1
+ {
2
+ "dependencies": {
3
+ "@cap-js/telemetry": ">=0",
4
+ "@grpc/grpc-js": "^1",
5
+ "@opentelemetry/exporter-trace-otlp-grpc": "^0",
6
+ "@opentelemetry/exporter-metrics-otlp-grpc": "^0",
7
+ "@opentelemetry/host-metrics": "^0"
8
+ },
9
+ "cds": {
10
+ "requires": {
11
+ "telemetry": "to-cloud-logging"
12
+ }
13
+ }
14
+ }