@sap/cds-dk 6.3.2 → 6.4.1

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 (93) hide show
  1. package/CHANGELOG.md +38 -7
  2. package/bin/cds.js +2 -0
  3. package/bin/compile/index.js +2 -1
  4. package/bin/deploy/index.js +5 -3
  5. package/bin/deploy/to-sqlite.js +17 -15
  6. package/bin/help.js +7 -4
  7. package/bin/init.js +1 -1
  8. package/bin/login.js +3 -4
  9. package/bin/migrate.js +33 -0
  10. package/bin/pull.js +4 -4
  11. package/bin/push.js +1 -1
  12. package/bin/subscribe.js +58 -66
  13. package/bin/unsubscribe.js +67 -0
  14. package/bin/watch.js +4 -3
  15. package/lib/bind/bindingUtil.js +2 -0
  16. package/lib/bind/cfKeyProvider.js +5 -1
  17. package/lib/client/activate.js +3 -3
  18. package/lib/client/auth_manager.js +2 -2
  19. package/lib/client/base_command.js +7 -6
  20. package/lib/client/extend.js +2 -2
  21. package/lib/client/helper/errors.js +8 -2
  22. package/lib/client/helper/logging.js +13 -11
  23. package/lib/client/params.js +3 -0
  24. package/lib/client/pull.js +1 -1
  25. package/lib/client/push.js +4 -4
  26. package/lib/client/settings_manager.js +13 -6
  27. package/lib/client/subscription.js +81 -0
  28. package/lib/compile/to-xsuaa.js +25 -19
  29. package/lib/import/odata/metadataconverter/MetadataConverter.js +3 -3
  30. package/lib/import/odata/v2parser.js +37 -24
  31. package/lib/import/odata/v4parser.js +111 -37
  32. package/lib/init/constants.js +1 -1
  33. package/lib/init/index.js +2 -2
  34. package/lib/init/template/_merging/registry-mta.js +0 -3
  35. package/lib/init/template/approuter/files/approuter-configmap.yaml +10 -0
  36. package/lib/init/template/approuter/files/approuter-mtxs-configmap.yaml +15 -0
  37. package/lib/init/template/approuter/files/chart.yaml +4 -0
  38. package/lib/init/template/approuter/files/package.json +1 -1
  39. package/lib/init/template/approuter/files/values.yaml.hbs +31 -0
  40. package/lib/init/template/approuter/index.js +60 -12
  41. package/lib/init/template/auditlog/index.js +16 -8
  42. package/lib/init/template/cf-manifest/index.js +3 -3
  43. package/lib/init/template/connectivity/index.js +19 -10
  44. package/lib/init/template/destinations/index.js +23 -7
  45. package/lib/init/template/enterprise-messaging/files/cds.package.json +1 -2
  46. package/lib/init/template/enterprise-messaging/files/cds.profile.package.json.hbs +1 -2
  47. package/lib/init/template/enterprise-messaging/files/cdsrc.json +1 -2
  48. package/lib/init/template/enterprise-messaging/files/cdsrc.json.hbs +1 -2
  49. package/lib/init/template/enterprise-messaging/files/event-mesh.json.hbs +31 -0
  50. package/lib/init/template/enterprise-messaging/files/mta.yaml.hbs +1 -0
  51. package/lib/init/template/enterprise-messaging/index.js +26 -13
  52. package/lib/init/template/extensibility/index.js +19 -10
  53. package/lib/init/template/hana/files/mta.yaml.hbs +0 -4
  54. package/lib/init/template/hana/index.js +58 -22
  55. package/lib/init/template/helm/chart/templates/NOTES.txt +4 -3
  56. package/lib/init/template/helm/chart/templates/_deployment_helpers.tpl +25 -2
  57. package/lib/init/template/helm/chart/values.root.schema.json +5 -0
  58. package/lib/init/template/helm/chart/values.schema.json +27 -0
  59. package/lib/init/template/helm/files/values.yaml.hbs +1 -1
  60. package/lib/init/template/helm/index.js +25 -23
  61. package/lib/init/template/helm/subchart/templates/_helpers.tpl +29 -0
  62. package/lib/init/template/helm/subchart/templates/api-rule.yaml +5 -5
  63. package/lib/init/template/helm/subchart/templates/deployment.yaml +12 -9
  64. package/lib/init/template/helm/subchart/values.md +258 -88
  65. package/lib/init/template/helm/subchart/values.schema.json +96 -13
  66. package/lib/init/template/helm/subchart/values.yaml +6 -2
  67. package/lib/init/template/html5-repo/index.js +28 -11
  68. package/lib/init/template/java/index.js +5 -5
  69. package/lib/init/template/kibana-logging/index.js +5 -4
  70. package/lib/init/template/mta/index.js +2 -2
  71. package/lib/init/template/mtx/index.js +1 -1
  72. package/lib/init/template/multitenancy/files/chart.yaml +4 -0
  73. package/lib/init/template/multitenancy/files/java/mtxs-configmap.yaml +20 -0
  74. package/lib/init/template/multitenancy/files/java/package.json +6 -9
  75. package/lib/init/template/multitenancy/files/mtxs-configmap.yaml +15 -0
  76. package/lib/init/template/multitenancy/files/saas-registry.yaml +17 -19
  77. package/lib/init/template/multitenancy/files/values.yaml.hbs +47 -0
  78. package/lib/init/template/multitenancy/files/xs-security.json.hbs +0 -7
  79. package/lib/init/template/multitenancy/index.js +83 -37
  80. package/lib/init/template/nodejs/files/.eslintrc +26 -0
  81. package/lib/init/template/nodejs/files/package.json.hbs +0 -28
  82. package/lib/init/template/nodejs/index.js +7 -10
  83. package/lib/init/template/pipeline/index.js +4 -4
  84. package/lib/init/template/samples/index.js +5 -5
  85. package/lib/init/template/templateBase.js +1 -4
  86. package/lib/init/template/toggles/index.js +5 -5
  87. package/lib/init/template/xsuaa/files/values.yaml.hbs +21 -0
  88. package/lib/init/template/xsuaa/index.js +34 -24
  89. package/lib/init/util/md5Tracking.js +113 -0
  90. package/lib/init/util/merge.js +19 -2
  91. package/lib/init/util/projectReader.js +15 -12
  92. package/npm-shrinkwrap.json +211 -686
  93. package/package.json +3 -3
@@ -4,7 +4,6 @@
4
4
  */
5
5
 
6
6
  "use strict";
7
-
8
7
  let messages = require("../message").getMessages();
9
8
  let common = require("../common");
10
9
  let versionInfo = require("../../../package.json").version;
@@ -71,6 +70,8 @@ function _initialize(parserContext) {
71
70
  parserContext.unboundedFunctions = {};
72
71
  parserContext.boundedFunctions = {};
73
72
  parserContext.entityTypes = [];
73
+ parserContext.entityTypeOpenEntries = [];
74
+ parserContext.complexTypeOpenEntries = [];
74
75
  parserContext.namespace = "";
75
76
  parserContext.complexTypes = {};
76
77
  parserContext.enumTypes = {};
@@ -100,11 +101,7 @@ function _isValidDataType(propertyType) {
100
101
  }
101
102
 
102
103
  function _isValidJSON(jsonObj, parserContext) {
103
- let tempNamespace = jsonObj.$EntityContainer;
104
- parserContext.namespace = tempNamespace.substring(0, tempNamespace.lastIndexOf('.'));
105
- parserContext.jsonEntityContainerName = tempNamespace.substring(tempNamespace.lastIndexOf('.') + 1);
106
-
107
- if (jsonObj.$Version && jsonObj.$EntityContainer && jsonObj[parserContext.namespace]) {
104
+ if (jsonObj.$Version && _hasEntityContainer(jsonObj, parserContext) && jsonObj[parserContext.namespace]) {
108
105
  return true;
109
106
  }
110
107
  else {
@@ -113,22 +110,24 @@ function _isValidJSON(jsonObj, parserContext) {
113
110
  }
114
111
 
115
112
  function _hasEntityContainer(jsonObj, parserContext) {
116
- if (jsonObj[parserContext.namespace][parserContext.jsonEntityContainerName] &&
117
- jsonObj[parserContext.namespace][parserContext.jsonEntityContainerName] instanceof Object
118
- ) {
119
- return true;
120
- } else {
113
+ let jsonObjEntityContainer = jsonObj.$EntityContainer;
114
+ try {
115
+ if (jsonObjEntityContainer) {
116
+ // scenario: Schema Namespace="A.B.C.D" & jsonObjEntityContainer is "A.B.C.D.EntityContainerName"
117
+ let lastIndex = jsonObjEntityContainer.lastIndexOf('.');
118
+ parserContext.namespace = jsonObjEntityContainer.substring(0, lastIndex);
119
+ parserContext.jsonEntityContainerName = jsonObjEntityContainer.substring(lastIndex + 1);
120
+ }
121
+ if (jsonObj[parserContext.namespace][parserContext.jsonEntityContainerName] &&
122
+ jsonObj[parserContext.namespace][parserContext.jsonEntityContainerName] instanceof Object
123
+ ) {
124
+ return true;
125
+ }
126
+ } catch (err) {
121
127
  throw new Error(messages.MISSING_ENTITY_CONTAINER);
122
128
  }
123
129
  }
124
130
 
125
- function _validateJSON(jsonObj, parserContext) {
126
- return (
127
- _isValidJSON(jsonObj, parserContext) &&
128
- _hasEntityContainer(jsonObj, parserContext)
129
- );
130
- }
131
-
132
131
  function _includeExternalNamespaceAnnotation(source, target) {
133
132
  Object.entries(source).forEach(element => {
134
133
  if (element[0].startsWith('@')) {
@@ -137,6 +136,11 @@ function _includeExternalNamespaceAnnotation(source, target) {
137
136
  });
138
137
  }
139
138
 
139
+ function _addNotNull(property, isCollection) {
140
+ if (isCollection) property.items["notNull"] = true;
141
+ else property["notNull"] = true;
142
+ }
143
+
140
144
  function _typeWithCollections(property, type, isCollection) {
141
145
  if (isCollection === true) {
142
146
  let typeKeys = Object.keys(type);
@@ -166,7 +170,9 @@ function generatePropertyCsn(propertyType, isPrimaryKey) {
166
170
  typeProperties["notNull"] = true;
167
171
  }
168
172
  else {
169
- typeProperties["notNull"] = propertyType.$Nullable ? false : true;
173
+ if ((propertyType.$Nullable !== true) && (propertyType.$Kind !== 'TypeDefinition')) {
174
+ typeProperties["notNull"] = true;
175
+ }
170
176
  }
171
177
  _includeExternalNamespaceAnnotation(propertyType, property);
172
178
  // conditions have to be made
@@ -225,16 +231,18 @@ function _generateComplexTypePropertyCsn(propertyType) {
225
231
  let property = {};
226
232
  let type = { type: propertyType.$Type }
227
233
  _typeWithCollections(property, type, propertyType.$Collection);
234
+ if (!propertyType.$Nullable) _addNotNull(property, propertyType.$Collection);
228
235
 
229
236
  return property;
230
237
  }
231
238
 
232
239
  function _generateTypeDefinitionPropertyCsn(propertyType) {
233
240
  let property = {};
234
- let type = { type: propertyType.$Type }
241
+ let type = { type: propertyType.$Type };
235
242
 
236
243
  _includeExternalNamespaceAnnotation(propertyType, property);
237
244
  _typeWithCollections(property, type, propertyType.$Collection);
245
+ if (!propertyType.$Nullable) _addNotNull(property, propertyType.$Collection);
238
246
 
239
247
  return property;
240
248
  }
@@ -251,6 +259,11 @@ function _parseAssociationProperty(foreignReference, associationNode, mockServer
251
259
  // annotation for ON condition
252
260
  associationProperty["@cds.ambiguous"] = 'missing on condition?';
253
261
  // associationProperty.target = associationNode.$Type;
262
+
263
+ //Code for NavigationProperty for notNull
264
+ /*if(associationProperty.$Nullable != true){
265
+ associationProperty["notNull"] = true;
266
+ }*/
254
267
  if (mockServerUc && parserContext.entitySetToEntityTypeMap && parserContext.entitySetToEntityTypeMap.get(associationNode.$Type)) {
255
268
  if (parserContext.entitySetToEntityTypeMap.get(associationNode.$Type).length > 1) {
256
269
  for (let j = 0; j < parserContext.entitySetToEntityTypeMap.get(associationNode.$Type).length; j++) {
@@ -333,6 +346,7 @@ function _generateCSNForEntityType(ignorePersistenceSkip, mockServerUc, parserCo
333
346
  let key = Object.keys(element)[0];
334
347
  let baseType = element[key].$BaseType;
335
348
  let isAbstract = element[key].$Abstract;
349
+ let isOpenType = element[key].$OpenType;
336
350
  if (key) {
337
351
  entityCsn[key] = {};
338
352
  entityCsn[key].kind = 'entity';
@@ -355,9 +369,10 @@ function _generateCSNForEntityType(ignorePersistenceSkip, mockServerUc, parserCo
355
369
  baseType = _getBaseTypeEntityName(baseType, parserContext);
356
370
  }
357
371
  entityCsn[key].includes.push(baseType);
372
+ if (!parserContext.entityTypeOpenEntries.includes(baseType)) parserContext.entityTypeOpenEntries.push(baseType);
358
373
  }
359
- if (isAbstract) {
360
- entityCsn[key].abstract = isAbstract;
374
+ if ((isAbstract || isOpenType) && !parserContext.entityTypeOpenEntries.includes(key)) {
375
+ parserContext.entityTypeOpenEntries.push(key);
361
376
  }
362
377
  entityCsn[key].elements = {};
363
378
  keySet = [];
@@ -408,6 +423,12 @@ function _generateCSNForEntityType(ignorePersistenceSkip, mockServerUc, parserCo
408
423
  }
409
424
  }
410
425
  });
426
+
427
+ // add @open annotations
428
+ parserContext.entityTypeOpenEntries.forEach(key => {
429
+ if (entityCsn[key]) entityCsn[key]['@open'] = true;
430
+ });
431
+
411
432
  return entityCsn;
412
433
  }
413
434
 
@@ -579,6 +600,26 @@ function _generateBounded(schemaData, flag, parserContext) {
579
600
  return bFunction;
580
601
  }
581
602
 
603
+ function _captureOptionalParameter(annotation, path) {
604
+ let param = annotation[0].split('/');
605
+ let defaultvalue = annotation[1]["@Core.OptionalParameter"]["DefaultValue"];
606
+ if (path.params === undefined) {
607
+ _addDefaultValueObject(path, defaultvalue);
608
+ }
609
+ else {
610
+ _addDefaultValueObject(path.params[param[1]], defaultvalue);
611
+ }
612
+ return path;
613
+ }
614
+
615
+ function _addDefaultValueObject(path, defaultvalue) {
616
+ // for collection, default value isin't expected
617
+ if (path.items === undefined) {
618
+ path.default = {};
619
+ path.default.val = (defaultvalue) ? defaultvalue : null;
620
+ }
621
+ }
622
+
582
623
  function _collectBounded(schemaDataList, flag, parserContext) {
583
624
  let schemaData;
584
625
  for (let i = 0; i < schemaDataList.length; i++) {
@@ -677,14 +718,16 @@ function _parseBounded(csnDefs, flag, parserContext) {
677
718
  if (paramObj.$Collection && !paramType.items) {
678
719
  csnDefs[boundedEntityName].actions[name].params[paramName] = {};
679
720
  csnDefs[boundedEntityName].actions[name].params[paramName].items = paramType;
680
- csnDefs[boundedEntityName].actions[name].params[paramName].items["notNull"] = paramObj?.$Nullable ? false : true;
681
-
721
+ if(paramObj.$Nullable != true){
722
+ csnDefs[boundedEntityName].actions[name].params[paramName].items["notNull"] = true;
723
+ }
682
724
  } else {
683
725
  csnDefs[boundedEntityName].actions[name].params[paramName] = paramType;
684
726
  if (!paramType.items) {
685
- csnDefs[boundedEntityName].actions[name].params[paramName].notNull = paramObj?.$Nullable ? false : true;
727
+ if(paramObj.$Nullable != true){
728
+ csnDefs[boundedEntityName].actions[name].params[paramName].notNull = true;
729
+ }
686
730
  }
687
- }
688
731
  }
689
732
  }
690
733
  else {
@@ -718,12 +761,16 @@ function _parseBounded(csnDefs, flag, parserContext) {
718
761
  // check if return type is a collection
719
762
  if (obj[j].$ReturnType.$Collection && !returnType.items) {
720
763
  csnDefs[boundedEntityName].actions[name].returns.items = returnType;
721
- csnDefs[boundedEntityName].actions[name].returns.items["notNull"] = obj[j].$ReturnType?.$Nullable ? false : true
764
+ if(obj[j].$ReturnType.$Nullable != true){
765
+ csnDefs[boundedEntityName].actions[name].returns.items["notNull"] = true;
766
+ }
722
767
  }
723
768
  else {
724
769
  csnDefs[boundedEntityName].actions[name].returns = returnType;
725
770
  if (!returnType.items) {
726
- csnDefs[boundedEntityName].actions[name].returns["notNull"] = obj[j].$ReturnType?.$Nullable ? false : true
771
+ if(obj[j].$ReturnType.$Nullable != true){
772
+ csnDefs[boundedEntityName].actions[name].returns["notNull"] = true;
773
+ }
727
774
  }
728
775
  }
729
776
  }
@@ -736,6 +783,7 @@ function _parseBounded(csnDefs, flag, parserContext) {
736
783
  }
737
784
  }
738
785
  }
786
+ }
739
787
  });
740
788
  }
741
789
  }
@@ -768,7 +816,7 @@ function _generateCSNForComplexType(schemaData, parserContext) {
768
816
  let complexCsn = {};
769
817
  let cTypes;
770
818
  let propertyType;
771
- let baseType;
819
+ let baseType, isAbstract, isOpenType;
772
820
  let enumType;
773
821
  cTypes = _collectComplexType(schemaData, parserContext);
774
822
  Object.keys(cTypes).forEach(element => {
@@ -778,10 +826,16 @@ function _generateCSNForComplexType(schemaData, parserContext) {
778
826
  complexCsn[element].elements = {};
779
827
  // inheritance handling
780
828
  baseType = cTypes[element].$BaseType;
829
+ isAbstract = cTypes[element].$Abstract;
830
+ isOpenType = cTypes[element].$OpenType;
781
831
  if (baseType) {
782
832
  complexCsn[element].includes = [];
783
833
  complexCsn[element].includes.push(baseType);
834
+ if (!parserContext.complexTypeOpenEntries.includes(baseType)) parserContext.complexTypeOpenEntries.push(baseType);
784
835
  }
836
+ if ((isAbstract || isOpenType) && !parserContext.complexTypeOpenEntries.includes(element)) {
837
+ parserContext.complexTypeOpenEntries.push(element);
838
+ }
785
839
  Object.keys(cTypes[element]).forEach(property => { // cTypes[element][property].$Type.startsWith('Edm.')
786
840
  if (cTypes[element][property] instanceof Object) {
787
841
  if (!cTypes[element][property].$Type ||
@@ -793,6 +847,9 @@ function _generateCSNForComplexType(schemaData, parserContext) {
793
847
  } else if (parserContext.complexTypes[cTypes[element][property].$Type]) {
794
848
  propertyType = cTypes[element][property];
795
849
  complexCsn[element].elements[property] = _generateComplexTypePropertyCsn(propertyType);
850
+ } else if (parserContext.typeDefinitions[cTypes[element][property].$Type]) {
851
+ propertyType = cTypes[element][property];
852
+ complexCsn[element].elements[property] = _generateTypeDefinitionPropertyCsn(propertyType);
796
853
  } else if (parserContext.enumTypes[cTypes[element][property].$Type]) {
797
854
  enumType = cTypes[element][property];
798
855
  complexCsn[element].elements[property] = generatePropertyCsn(enumType, false);
@@ -805,6 +862,12 @@ function _generateCSNForComplexType(schemaData, parserContext) {
805
862
  }
806
863
  });
807
864
  });
865
+
866
+ // add @open annotations
867
+ parserContext.complexTypeOpenEntries.forEach(key => {
868
+ if (complexCsn[key]) complexCsn[key]['@open'] = true;
869
+ });
870
+
808
871
  return complexCsn;
809
872
  }
810
873
 
@@ -870,11 +933,15 @@ function _parseUnbounded(schemaData, flag, parserContext) {
870
933
  if (objData.$Parameter[i].$Collection && !paramType.items) {
871
934
  obj[objType].params[objData.$Parameter[i].$Name] = {};
872
935
  obj[objType].params[objData.$Parameter[i].$Name].items = paramType;
873
- obj[objType].params[objData.$Parameter[i].$Name].items["notNull"] = objData.$Parameter[i]?.$Nullable ? false : true;
936
+ if(objData.$Parameter[i].$Nullable != true){
937
+ obj[objType].params[objData.$Parameter[i].$Name].items["notNull"] = true;
938
+ }
874
939
  } else {
875
940
  obj[objType].params[objData.$Parameter[i].$Name] = paramType;
876
941
  if (!paramType.items) {
877
- obj[objType].params[objData.$Parameter[i].$Name]["notNull"] = objData.$Parameter[i]?.$Nullable ? false : true;
942
+ if(objData.$Parameter[i].$Nullable != true){
943
+ obj[objType].params[objData.$Parameter[i].$Name]["notNull"] = true;
944
+ }
878
945
  }
879
946
  }
880
947
  }
@@ -909,11 +976,15 @@ function _parseUnbounded(schemaData, flag, parserContext) {
909
976
  if (objData.$ReturnType.$Collection && !returnValue.items) {
910
977
  obj[objType].returns.items = {};
911
978
  obj[objType].returns.items = returnValue;
912
- obj[objType].returns.items["notNull"] = objData.$ReturnType?.$Nullable ? false : true;
979
+ if(objData.$ReturnType.$Nullable != true){
980
+ obj[objType].returns.items["notNull"] = true;
981
+ }
913
982
  } else {
914
983
  obj[objType].returns = returnValue;
915
984
  if (!returnValue.items) {
916
- obj[objType].returns["notNull"] = objData.$ReturnType?.$Nullable ? false : true;
985
+ if(objData.$ReturnType.$Nullable != true){
986
+ obj[objType].returns["notNull"] = true;
987
+ }
917
988
  }
918
989
  }
919
990
  }
@@ -1021,9 +1092,12 @@ function _checkAnnotatationTerm(annotation, path, no_of_terms, targetString, voc
1021
1092
  else if (targetString === "@Core.LongDescription" && annotation[1]["@Core.LongDescription"]) {
1022
1093
  _generateLongDescription(annotation, path, no_of_terms);
1023
1094
  }
1024
- else if (vocab) {
1095
+ else if (targetString === "@Core.OptionalParameter" && annotation[1]["@Core.OptionalParameter"]) {
1096
+ _captureOptionalParameter(annotation, path);
1097
+ }
1098
+ else if (vocab) {
1025
1099
  if (vocab.includes(targetString.substring(targetString.indexOf('@') + 1, targetString.lastIndexOf('.')))) {
1026
- path[targetString] = annotation[1][targetString];
1100
+ path[targetString] = annotation[1][targetString] === null ? true : annotation[1][targetString];
1027
1101
  }
1028
1102
  }
1029
1103
  }
@@ -1194,7 +1268,7 @@ function _generateEDMX2JSON(edmx, name_space, parserContext) {
1194
1268
  if (missingReferencedDocuments?.length > 0) {
1195
1269
  console.log(missingReferencedDocuments); // eslint-disable-line no-console
1196
1270
  }
1197
- if (_validateJSON(json, parserContext)) {
1271
+ if (_isValidJSON(json, parserContext)) {
1198
1272
  resolve(json);
1199
1273
  }
1200
1274
  });
@@ -1221,7 +1295,7 @@ async function getEdmxv4CSN(edmx, ignorePersistenceSkip, mockServerUc, context)
1221
1295
  return new Promise(function getCsn(resolve, reject) {
1222
1296
  try {
1223
1297
  edmjConverted = JSON.parse(edmx);
1224
- if (_validateJSON(edmjConverted, parserContext)) {
1298
+ if (_isValidJSON(edmjConverted, parserContext)) {
1225
1299
  csn = _generateCSN(edmjConverted, ignorePersistenceSkip, mockServerUc, parserContext);
1226
1300
  if (csn) resolve(csn);
1227
1301
  }
@@ -1,6 +1,6 @@
1
1
  const os = require('os');
2
2
 
3
- const MAVEN_ARCHETYPE_VERSION = '1.29.0';
3
+ const MAVEN_ARCHETYPE_VERSION = '1.30.0';
4
4
 
5
5
  const constants = {
6
6
  IS_WIN: (os.platform() === 'win32'),
package/lib/init/index.js CHANGED
@@ -267,8 +267,8 @@ module.exports = class CDSGenerator {
267
267
  }
268
268
  }
269
269
 
270
- this.templateList = Array.from(templates.entries()).sort((a, b) => {
271
- return OPTIONS_PRIORITY.indexOf(a[0]) - OPTIONS_PRIORITY.indexOf(b[0]);
270
+ this.templateList = Array.from(templates.entries()).sort(([a], [b]) => {
271
+ return OPTIONS_PRIORITY.indexOf(a) - OPTIONS_PRIORITY.indexOf(b);
272
272
  }).map((entry) => entry[1]);
273
273
 
274
274
  // check debug to avoid lengthy computation when not in debug mode
@@ -123,9 +123,6 @@ const saasRegistry = {
123
123
  }, {
124
124
  property: 'parameters.service',
125
125
  isEqualTo: 'saas-registry',
126
- }, {
127
- property: 'parameters.service-plan',
128
- isEqualTo: 'application'
129
126
  }]
130
127
  }
131
128
 
@@ -0,0 +1,10 @@
1
+ # Please do not modify this file. This file may be overwritten.
2
+
3
+ apiVersion: v1
4
+ kind: ConfigMap
5
+ metadata:
6
+ name: "{{ .Release.Name }}-approuter-configmap"
7
+ namespace: "{{ .Release.Namespace }}"
8
+ data:
9
+ destinations: >
10
+ {{ include "cap.approuterDestinations" . }}
@@ -0,0 +1,15 @@
1
+ # Please do not modify this file. This file may be overwritten.
2
+
3
+ {{- $deployment := .Values.approuter }}
4
+ {{- $ := merge (dict "name" "approuter" "deployment" $deployment) . }}
5
+ {{- $approuterUrl := (include "cap.deploymentHostFull" $ )}}
6
+
7
+ apiVersion: v1
8
+ kind: ConfigMap
9
+ metadata:
10
+ name: "{{ .Release.Name }}-approuter-configmap"
11
+ namespace: "{{ .Release.Namespace }}"
12
+ data:
13
+ destinations: >
14
+ {{ include "cap.approuterDestinations" . }}
15
+ TENANT_HOST_PATTERN: {{ printf "^(.*)-%s" $approuterUrl }}
@@ -0,0 +1,4 @@
1
+ dependencies:
2
+ - name: web-application
3
+ alias: approuter
4
+ version: 0.1.0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "approuter",
3
3
  "dependencies": {
4
- "@sap/approuter": "^11.0.0"
4
+ "@sap/approuter": "^12.0.0"
5
5
  },
6
6
  "engines": {
7
7
  "node": "^16"
@@ -0,0 +1,31 @@
1
+ ---
2
+ {{#cap.hasXsuaa}}
3
+ xsuaa:
4
+ parameters:
5
+ oauth2-configuration:
6
+ redirect-uris:
7
+ - https://*.<your-cluster-domain>/**
8
+ {{/cap.hasXsuaa}}
9
+ approuter:
10
+ {{#cap.hasXsuaa}}
11
+ bindings:
12
+ auth:
13
+ serviceInstanceName: xsuaa
14
+ {{/cap.hasXsuaa}}
15
+ image:
16
+ repository: <your-container-registry>/{{cap.appName}}-approuter
17
+ tag: latest
18
+ resources:
19
+ limits:
20
+ ephemeral-storage: 1G
21
+ memory: 500M
22
+ requests:
23
+ ephemeral-storage: 1G
24
+ cpu: 500m
25
+ memory: 500M
26
+ health:
27
+ liveness:
28
+ path: /
29
+ readiness:
30
+ path: /
31
+ approuterDestinations: {}
@@ -9,6 +9,7 @@ const {
9
9
  requiredAppAPI, providedAppAPI,
10
10
  approuterExtensibility, approuterExtensibilityJava // xs-app.json config
11
11
  } = require('../_merging/registry-mta')
12
+ const { copyAndTrack, parseMd5File, writeMd5File } = require('../../util/md5Tracking')
12
13
 
13
14
  module.exports = class ApprouterTemplate extends require('../templateBase') {
14
15
 
@@ -21,16 +22,7 @@ module.exports = class ApprouterTemplate extends require('../templateBase') {
21
22
  return !!env.requires?.approuter
22
23
  }
23
24
 
24
- async canRun() {
25
- const projectDescriptor = await this.projectReader.read(this.options)
26
- const { hasMta, hasHelm } = projectDescriptor.cap
27
- if (hasHelm && !hasMta) {
28
- throw `'cds add approuter' is not available for Kyma yet`
29
- }
30
- return true
31
- }
32
-
33
- async getDependencies() {
25
+ getDependencies() {
34
26
  return [OPTION_XSUAA]
35
27
  }
36
28
 
@@ -66,9 +58,9 @@ module.exports = class ApprouterTemplate extends require('../templateBase') {
66
58
  await this.runDependentMerging()
67
59
  }
68
60
 
69
- async runDependentMerging() {
61
+ async runDependentMerging(context = {}) {
70
62
  const projectDescriptor = await this.projectReader.read(this.options)
71
- const { isNodejs, isJava, isExtensible, isMultitenant, hasMta } = projectDescriptor.cap
63
+ const { isNodejs, isJava, isExtensible, isMultitenant, hasMta, hasHelm } = projectDescriptor.cap
72
64
 
73
65
  if (hasMta) {
74
66
  const srv = isNodejs ? srvNode : srvJava
@@ -89,6 +81,62 @@ module.exports = class ApprouterTemplate extends require('../templateBase') {
89
81
  })
90
82
  }
91
83
 
84
+ if (hasHelm) {
85
+ let isIndependentCommand = false;
86
+ if (Object.keys(context).length == 0) {
87
+ isIndependentCommand = true;
88
+ context.projectPath = this.projectPath;
89
+ context.oldTrackingData = context.newTrackingData = await parseMd5File(join(this.projectPath, 'chart', '.cds-add-helm-files.md5'));
90
+ }
91
+
92
+ await mergeYAML(
93
+ join(this.projectPath, 'chart', 'values.yaml'),
94
+ join(__dirname, 'files', 'values.yaml.hbs'),
95
+ projectDescriptor
96
+ )
97
+
98
+ await mergeYAML(
99
+ join(this.projectPath, 'chart', 'Chart.yaml'),
100
+ join(__dirname, 'files', 'chart.yaml'),
101
+ projectDescriptor,
102
+ { additions: [{
103
+ ref: `web-application-approuter`,
104
+ in: `dependencies`,
105
+ where: [{
106
+ property: 'alias',
107
+ isEqualTo: 'approuter'
108
+ }]
109
+ }]}
110
+ )
111
+ await mergeYAML(
112
+ join(this.projectPath, 'chart', 'values.yaml'),
113
+ {
114
+ approuter: {
115
+ envFrom: [
116
+ {
117
+ configMapRef: {
118
+ name: "{{ .Release.Name }}-approuter-configmap",
119
+ tpl: true
120
+ }
121
+ }
122
+ ]
123
+ }
124
+ },
125
+ projectDescriptor
126
+ )
127
+
128
+ const fileName = isMultitenant ? 'approuter-mtxs-configmap.yaml' : 'approuter-configmap.yaml';
129
+
130
+ await copyAndTrack(
131
+ join(__dirname, 'files', fileName),
132
+ join(this.projectPath, 'chart', 'templates', 'approuter-configmap.yaml'),
133
+ context,
134
+ true
135
+ )
136
+
137
+ if (isIndependentCommand) await writeMd5File(join(this.projectPath, 'chart', '.cds-add-helm-files.md5'), context.newTrackingData);
138
+ }
139
+
92
140
  const appPath = join(this.projectPath, projectDescriptor.ui.appPath || 'app')
93
141
  const additions = isExtensible && isJava ? [{ ...approuterExtensibilityJava, at: 0 }] :
94
142
  isExtensible && isNodejs ? [{ ...approuterExtensibility, at: 0 }] : []
@@ -1,7 +1,7 @@
1
- const path = require('path')
2
- const { copy } = require('../../../cds').utils
1
+ const { join } = require('path')
3
2
  const ProjectReader = require('../../util/projectReader')
4
3
  const { mergeYAML } = require('../../util/merge')
4
+ const { copyAndTrack, parseMd5File, writeMd5File } = require('../../util/md5Tracking')
5
5
  const { srvNode, srvJava, auditlog } = require('../_merging/registry-mta')
6
6
 
7
7
  module.exports = class AuditlogTemplate extends require('../templateBase') {
@@ -18,12 +18,12 @@ module.exports = class AuditlogTemplate extends require('../templateBase') {
18
18
  await this.runDependentMerging()
19
19
  }
20
20
 
21
- async runDependentMerging() {
21
+ async runDependentMerging(context = {}) {
22
22
  const projectDescriptor = await this.projectReader.read(this.options)
23
23
  const { isNodejs, hasMta, hasHelm } = projectDescriptor.cap
24
24
 
25
25
  if (hasMta) {
26
- const mtaYAMLPath = path.join(this.projectPath, 'mta.yaml')
26
+ const mtaYAMLPath = join(this.projectPath, 'mta.yaml')
27
27
  const srv = isNodejs ? srvNode : srvJava
28
28
  await mergeYAML(
29
29
  mtaYAMLPath,
@@ -40,8 +40,16 @@ module.exports = class AuditlogTemplate extends require('../templateBase') {
40
40
  }
41
41
 
42
42
  if (hasHelm) {
43
+ //in case facet is being added to the already exisiting charts folder
44
+ let isIndependentCommand = false
45
+ if(Object.keys(context).length == 0){
46
+ isIndependentCommand = true
47
+ context.projectPath = this.projectPath
48
+ context.oldTrackingData = context.newTrackingData = await parseMd5File(join(this.projectPath, 'chart', '.cds-add-helm-files.md5'))
49
+ }
50
+
43
51
  await mergeYAML(
44
- path.join(this.projectPath, 'chart', 'values.yaml'),
52
+ join(this.projectPath, 'chart', 'values.yaml'),
45
53
  {
46
54
  srv: { bindings: {
47
55
  auditlog: { serviceInstanceName: 'auditlog' }
@@ -50,10 +58,10 @@ module.exports = class AuditlogTemplate extends require('../templateBase') {
50
58
  serviceOfferingName: 'auditlog-api',
51
59
  servicePlanName: 'default'
52
60
  }
53
- },
54
- null, { forceOverwrite: true }
61
+ }
55
62
  )
56
- await copy(path.join(__dirname, 'files', 'auditlog.yaml'), path.join(this.projectPath, 'chart', 'templates', 'auditlog.yaml'))
63
+ await copyAndTrack(join(__dirname, 'files', 'auditlog.yaml'), join(this.projectPath, 'chart', 'templates', 'auditlog.yaml'), context)
64
+ if(isIndependentCommand) await writeMd5File(join(this.projectPath, 'chart', '.cds-add-helm-files.md5'), context.newTrackingData)
57
65
  }
58
66
  }
59
67
  }
@@ -1,4 +1,4 @@
1
- const path = require('path')
1
+ const { join } = require('path')
2
2
  const { exists } = require('../../../cds').utils
3
3
  const ProjectReader = require('../../util/projectReader');
4
4
  const { copyFiles } = require('../../util/templateUtil')
@@ -21,7 +21,7 @@ module.exports = class ManifestTemplate extends require('../templateBase') {
21
21
  return true;
22
22
  }
23
23
 
24
- if (exists(path.join(this.projectPath, MANIFEST_FILE)) || exists(path.join(this.projectPath, SERVICES_MANIFEST_FILE))) {
24
+ if (exists(join(this.projectPath, MANIFEST_FILE)) || exists(join(this.projectPath, SERVICES_MANIFEST_FILE))) {
25
25
  throw new Error(`File ${MANIFEST_FILE} or ${SERVICES_MANIFEST_FILE} already exist in current folder. Use --force to overwrite.`);
26
26
  }
27
27
  return true;
@@ -29,6 +29,6 @@ module.exports = class ManifestTemplate extends require('../templateBase') {
29
29
 
30
30
  async run() {
31
31
  const projectDescriptor = await this.projectReader.read()
32
- await copyFiles(path.join(__dirname, 'files'), this.projectPath, projectDescriptor, this.options.force);
32
+ await copyFiles(join(__dirname, 'files'), this.projectPath, projectDescriptor, this.options.force);
33
33
  }
34
34
  }