@sap/cds-dk 4.9.7 → 6.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/CHANGELOG.md +77 -0
  2. package/bin/activate.js +4 -4
  3. package/bin/add.js +11 -5
  4. package/bin/bind.js +16 -28
  5. package/bin/build/all.js +2 -2
  6. package/bin/build/index.js +12 -19
  7. package/bin/cds.js +22 -19
  8. package/bin/compile/index.js +12 -3
  9. package/bin/deploy/index.js +15 -9
  10. package/bin/deploy/to-hana.js +4 -4
  11. package/bin/deploy/to-sqlite.js +1 -1
  12. package/bin/env.js +13 -4
  13. package/bin/eval.js +1 -1
  14. package/bin/fix-redirects.js +1 -1
  15. package/bin/import.js +44 -179
  16. package/bin/repl.js +1 -1
  17. package/bin/watch.js +10 -15
  18. package/lib/bind/BindingManager.js +87 -0
  19. package/lib/bind/bindingResolver.js +15 -87
  20. package/lib/bind/bindingUtil.js +18 -11
  21. package/lib/bind/cfKeyProvider.js +58 -29
  22. package/lib/bind/kubernetesCredentialsProvider.js +44 -21
  23. package/lib/bind/userCdsrcJsonStorageProvider.js +12 -18
  24. package/lib/cds.js +13 -0
  25. package/lib/client/base_command.js +3 -2
  26. package/lib/client/extend.js +6 -7
  27. package/lib/client/helper/fs_helper.js +7 -8
  28. package/lib/client/settings_manager.js +14 -10
  29. package/lib/compile/index.js +9 -10
  30. package/lib/compile/openapi/csdl2openapi.js +151 -43
  31. package/lib/compile/openapi/index.js +2 -2
  32. package/lib/compile/to-xsuaa.js +3 -2
  33. package/lib/import/common.js +342 -27
  34. package/lib/import/importapi.js +81 -13
  35. package/lib/import/message.js +4 -4
  36. package/lib/import/odata/index.js +141 -0
  37. package/lib/import/{utils → odata/metadataconverter}/MetadataConverter.js +2 -2
  38. package/lib/import/{utils → odata/metadataconverter}/MetadataConverterFactory.js +1 -1
  39. package/lib/import/{utils → odata/util}/MultiMap.js +0 -0
  40. package/lib/import/{v2parser.js → odata/v2parser.js} +405 -468
  41. package/lib/import/{v4parser.js → odata/v4parser.js} +311 -322
  42. package/lib/import/{vocabularies → odata/vocabularies}/Org.OData.Aggregation.V1.json +0 -0
  43. package/lib/import/{vocabularies → odata/vocabularies}/Org.OData.Authorization.V1.json +0 -0
  44. package/lib/import/{vocabularies → odata/vocabularies}/Org.OData.Capabilities.V1.json +0 -0
  45. package/lib/import/{vocabularies → odata/vocabularies}/Org.OData.Core.V1.json +0 -0
  46. package/lib/import/{vocabularies → odata/vocabularies}/Org.OData.Measures.V1.json +0 -0
  47. package/lib/import/{vocabularies → odata/vocabularies}/Org.OData.Validation.V1.json +0 -0
  48. package/lib/import/openapi/importOpenAPI.js +521 -0
  49. package/lib/import/openapi/index.js +19 -0
  50. package/lib/import/openapi/utilities.js +38 -0
  51. package/lib/index.js +1 -1
  52. package/lib/init/constants.js +7 -2
  53. package/lib/init/index.js +10 -3
  54. package/lib/init/template/_merging/existences.js +79 -19
  55. package/lib/init/template/approuter/files/mta.yaml.hbs +25 -11
  56. package/lib/init/template/approuter/files/package.json +1 -1
  57. package/lib/init/template/approuter/files/xs-app.json.hbs +7 -0
  58. package/lib/init/template/approuter/index.js +61 -54
  59. package/lib/init/template/auditlog/index.js +2 -2
  60. package/lib/init/template/data/index.js +2 -2
  61. package/lib/init/template/hana/files/mta.yaml.hbs +17 -17
  62. package/lib/init/template/hana/index.js +8 -4
  63. package/lib/init/template/helm/index.js +39 -0
  64. package/lib/init/template/helm/update/index.js +28 -0
  65. package/lib/init/template/java/index.js +7 -9
  66. package/lib/init/template/kibana-logging/index.js +5 -6
  67. package/lib/init/template/lint/index.js +1 -1
  68. package/lib/init/template/mta/index.js +4 -4
  69. package/lib/init/template/mtx/files/java/package.json +9 -9
  70. package/lib/init/template/mtx/files/mta.yaml.hbs +0 -7
  71. package/lib/init/template/mtx/files/xs-security.json.hbs +11 -20
  72. package/lib/init/template/mtx/index.js +50 -57
  73. package/lib/init/template/nodejs/files/package.json.hbs +2 -2
  74. package/lib/init/template/notebook/index.js +2 -0
  75. package/lib/init/template/templateBase.js +8 -6
  76. package/lib/init/template/xsuaa/index.js +9 -5
  77. package/lib/init/util/fsUtil.js +25 -10
  78. package/lib/init/util/logger.js +1 -1
  79. package/lib/init/util/mvnArchetypeUtil.js +4 -10
  80. package/lib/init/util/projectReader.js +17 -9
  81. package/lib/init/util/templateUtil.js +30 -34
  82. package/lib/k8s/ChartAdder.js +65 -0
  83. package/lib/k8s/ChartBuilder.js +186 -0
  84. package/lib/k8s/Context.js +71 -0
  85. package/lib/k8s/ImageUtil.js +21 -0
  86. package/lib/k8s/Model.d.ts +53 -0
  87. package/lib/k8s/auditlog/index.js +29 -0
  88. package/lib/k8s/auditlog/templates/auditlog.yaml +1 -0
  89. package/lib/k8s/buildModel.js +70 -0
  90. package/lib/k8s/connectivity/index.js +80 -0
  91. package/lib/k8s/connectivity/templates/connectivity-binding.yaml +9 -0
  92. package/lib/k8s/connectivity/templates/connectivity-proxy-info.yaml +20 -0
  93. package/lib/k8s/connectivity/templates/connectivity.yaml +1 -0
  94. package/lib/k8s/deployment/index.js +81 -0
  95. package/lib/k8s/deployment/subchart/Chart.yaml +6 -0
  96. package/lib/k8s/deployment/subchart/templates/_helpers.tpl +156 -0
  97. package/lib/k8s/deployment/subchart/templates/api-rule.yaml +24 -0
  98. package/lib/k8s/deployment/subchart/templates/deployment.yaml +110 -0
  99. package/lib/k8s/deployment/subchart/templates/network-policy.yaml +16 -0
  100. package/lib/k8s/deployment/subchart/templates/pod-disruption-budget.yaml +11 -0
  101. package/lib/k8s/deployment/subchart/templates/secret.yaml +10 -0
  102. package/lib/k8s/deployment/subchart/templates/service-binding.yaml +27 -0
  103. package/lib/k8s/deployment/subchart/templates/service.yaml +11 -0
  104. package/lib/k8s/deployment/subchart/values-lint.yaml +8 -0
  105. package/lib/k8s/deployment/subchart/values.schema.json +449 -0
  106. package/lib/k8s/deployment/subchart/values.yaml +76 -0
  107. package/lib/k8s/deployment/subchart-override/templates/_web_application_helpers.tpl +81 -0
  108. package/lib/k8s/destinations/index.js +40 -0
  109. package/lib/k8s/destinations/lib.js +16 -0
  110. package/lib/k8s/destinations/templates/destinations.yaml +1 -0
  111. package/lib/k8s/docker/push.js +8 -0
  112. package/lib/k8s/event-mesh/index.js +53 -0
  113. package/lib/k8s/event-mesh/lib.js +9 -0
  114. package/lib/k8s/event-mesh/templates/event-mesh.yaml +1 -0
  115. package/lib/k8s/hana-deployer/index.js +38 -0
  116. package/lib/k8s/hana-deployer/templates/hana-deployer-job.yaml +41 -0
  117. package/lib/k8s/helm/Release.js +80 -0
  118. package/lib/k8s/html5-apps-deployer/index.js +43 -0
  119. package/lib/k8s/html5-apps-deployer/templates/_html5_deployment_helpers.tpl +16 -0
  120. package/lib/k8s/html5-apps-deployer/templates/html5-apps-deployer-job.yaml +53 -0
  121. package/lib/k8s/html5-apps-repo-host/index.js +26 -0
  122. package/lib/k8s/html5-apps-repo-host/lib.js +16 -0
  123. package/lib/k8s/html5-apps-repo-host/templates/html5-apps-repo-host.yaml +1 -0
  124. package/lib/k8s/index.js +153 -0
  125. package/lib/k8s/modules.js +36 -0
  126. package/lib/k8s/multitenancy/index.js +24 -0
  127. package/lib/k8s/multitenancy/lib.js +25 -0
  128. package/lib/k8s/multitenancy/templates/saas-registry.yaml +19 -0
  129. package/lib/k8s/readProject.js +14 -0
  130. package/lib/k8s/resources/helm/chart/templates/NOTES.txt +11 -0
  131. package/lib/k8s/resources/helm/chart/templates/_deployment_helpers.tpl +221 -0
  132. package/lib/k8s/resources/helm/chart/templates/_helpers.tpl +167 -0
  133. package/lib/k8s/resources/helm/chart/templates/_sapcp_helpers.tpl +103 -0
  134. package/lib/k8s/util.js +186 -0
  135. package/lib/k8s/wrapFeature.js +55 -0
  136. package/lib/k8s/xsuaa/index.js +64 -0
  137. package/lib/k8s/xsuaa/lib.js +17 -0
  138. package/lib/k8s/xsuaa/templates/xsuaa.yaml +1 -0
  139. package/lib/lint/generators.js +1 -1
  140. package/lib/util/exec.js +1 -1
  141. package/lib/util/write.js +1 -1
  142. package/lib/watch/node-watch.js +43 -14
  143. package/npm-shrinkwrap.json +923 -2705
  144. package/package.json +5 -5
  145. package/lib/import/index.js +0 -235
@@ -4,26 +4,10 @@
4
4
 
5
5
  "use strict";
6
6
 
7
- let serviceNamespace;
8
- let allEntities = [];
9
- let allEntitiesMC = [];
10
- let allEntitySetMap = {};
11
- let allEntitySetMapMC = {};
12
- let allEntitySetNamespaces = {};
13
- let allFunctionImports = [];
14
- let allFunctionImportsMap = {};
15
- let allAssociations = {};
16
- let allAssociationSets = {};
17
- let allComplexTypes = {};
18
- let allComplexTypeDocs = {};
19
- let allComplexTypeNamespaces = {};
20
- let allInheritedComplexTypes = {};
21
- let allowedNamespaces = [];
22
- let allowAllNamespaces = false;
23
- let messages = require("./message").getMessages();
24
- let common = require("./common");
25
- let versionInfo = require('../../package.json').version;
26
- const { warn } = require('@sap/cds/bin/utils/term');
7
+ let messages = require("../message").getMessages();
8
+ let common = require("../common");
9
+ let versionInfo = require('../../../package.json').version;
10
+ const { warn } = require('../../util/term');
27
11
 
28
12
  let edmxncdsdatatype = {
29
13
  "Edm.String": "cds.LargeString",
@@ -31,14 +15,12 @@ let edmxncdsdatatype = {
31
15
  "Edm.Int16": "cds.Integer",
32
16
  "Edm.Int32": "cds.Integer",
33
17
  "Edm.Int64": "cds.Integer64",
34
- "Edm.Decimal": "cds.DecimalFloat",
35
- "Edm.DateTime": "cds.DateTime",
18
+ "Edm.Decimal": "cds.Decimal",
19
+ "Edm.DateTime": "cds.DateTime",
36
20
  "Edm.DateTimeOffset": "cds.DateTime",
37
21
  "Edm.Time": "cds.Time",
38
22
  "Edm.Binary": "cds.LargeBinary",
39
23
  "Edm.Guid": "cds.UUID",
40
- "Edm.Byte": "cds.Integer",
41
- "Edm.SByte": "cds.Integer",
42
24
  "Edm.Double": "cds.Double",
43
25
  // Special handling of data types
44
26
  "Edm.String_m": "cds.String", // Max length
@@ -49,38 +31,40 @@ let edmxncdsdatatype = {
49
31
  "Edm.Byte_m": "cds.Integer", // Max Length
50
32
  "Edm.Double_p": "cds.Double", // Precision, scale
51
33
  // Special handling with annotations
34
+ "Edm.Byte_a": "cds.Integer",
35
+ "Edm.SByte_a": "cds.Integer",
52
36
  "Edm.Single_a": "cds.Double",
53
- "Edm.Stream_a" : "cds.LargeBinary",
54
- "Edm.DateTimeOffset_a" : "cds.Timestamp", //precision > 0
55
- "Edm.DateTime_a" : "cds.Timestamp" //precision > 0
37
+ "Edm.Stream_a": "cds.LargeBinary",
38
+ "Edm.DateTimeOffset_a": "cds.Timestamp", //precision > 0
39
+ "Edm.DateTime_a": "cds.Timestamp" //precision > 0
56
40
  };
57
41
 
58
- function _initialize() {
59
- allEntities.length = 0;
60
- allEntitiesMC.length = 0;
61
- allEntitySetMap = {};
62
- allEntitySetMapMC = {};
63
- allFunctionImports.length = 0;
64
- allFunctionImportsMap = {};
65
- allAssociations = {};
66
- allAssociationSets = {};
67
- allComplexTypes = {};
68
- allComplexTypeDocs = {};
69
- allComplexTypeNamespaces = {};
70
- allInheritedComplexTypes = {};
71
- allowedNamespaces = [];
72
- allowAllNamespaces = false;
42
+ function _initialize(parserContext) {
43
+ parserContext.serviceNamespace = "";
44
+ parserContext.allEntities = [];
45
+ parserContext.allEntitiesMC = [];
46
+ parserContext.allEntitySetMap = {};
47
+ parserContext.allEntitySetMapMC = {};
48
+ parserContext.allEntitySetNamespaces = {};
49
+ parserContext.allFunctionImports = [];
50
+ parserContext.allFunctionImportsMap = {};
51
+ parserContext.allAssociations = {};
52
+ parserContext.allAssociationSets = {};
53
+ parserContext.allComplexTypes = {};
54
+ parserContext.allComplexTypeDocs = {};
55
+ parserContext.allComplexTypeNamespaces = {};
56
+ parserContext.allInheritedComplexTypes = {};
57
+ parserContext.allowedNamespaces = [];
58
+ parserContext.allowAllNamespaces = false;
73
59
  }
74
60
 
75
61
  // Function to extract allowed namespace attributes from given set of attributes
76
- function namespaceAttributeFilter(attributes) {
77
- let namespaceAttributes = allowAllNamespaces
62
+ function namespaceAttributeFilter(attributes, parserContext) {
63
+ let namespaceAttributes = parserContext.allowAllNamespaces
78
64
  ? Object.keys(attributes).filter((attr) => attr.includes(':'))
79
- : Object.keys(attributes).filter(
80
- (attr) =>
81
- attr.includes(':') &&
82
- allowedNamespaces.includes(attr.split(':')[0]));
83
-
65
+ : Object.keys(attributes).filter((attr) =>
66
+ attr.includes(':') && parserContext.allowedNamespaces.includes(attr.split(':')[0]));
67
+
84
68
 
85
69
  namespaceAttributes = namespaceAttributes.map(attribute => {
86
70
  const index = attribute.indexOf(':');
@@ -92,6 +76,7 @@ function namespaceAttributeFilter(attributes) {
92
76
  let formattedAttribute = {};
93
77
  formattedAttribute[`${namespace}.${name}`] = _replaceSpecialCharacters(attributes[attribute]);
94
78
  return formattedAttribute;
79
+
95
80
  });
96
81
 
97
82
  return namespaceAttributes;
@@ -102,13 +87,16 @@ function _generateNamespaceAttributes(attributes, isBefore) {
102
87
  let csn = "";
103
88
  attributes.forEach((attr) => {
104
89
  let key = Object.keys(attr)[0];
105
- if (isBefore) csn = csn + ',\n';
106
- csn = csn + `"@${key}":"${attr[key]}"`;
107
- if (!isBefore) csn = csn + ',\n';
90
+ if (key !== 'm.HasStream') {
91
+ if (isBefore) csn = csn + ',\n';
92
+ csn = csn + `"@${key}":"${attr[key]}"`;
93
+ if (!isBefore) csn = csn + ',\n';
94
+ }
108
95
  });
109
96
 
110
97
  return csn;
111
98
  }
99
+
112
100
  function _isValidEDMX(jsonObj) {
113
101
  let isValid = false;
114
102
  let edmx;
@@ -130,22 +118,13 @@ function _isValidEDMX(jsonObj) {
130
118
  }
131
119
 
132
120
  function _hasEntityContainer(jsonObj) {
133
- let isEntityContainerPresent = !!jsonObj["edmx:Edmx"]["edmx:DataServices"]
134
- .Schema.EntityContainer;
121
+ let isEntityContainerPresent = !!jsonObj["edmx:Edmx"]["edmx:DataServices"].Schema.EntityContainer;
135
122
  if (!isEntityContainerPresent) {
136
123
  throw new Error(messages.MISSING_ENTITY_CONTAINER);
137
124
  }
138
125
  return isEntityContainerPresent;
139
126
  }
140
127
 
141
- function _hasEntitySet(jsonObj) {
142
- let isEntitySetPresent = !!jsonObj['edmx:Edmx']['edmx:DataServices'].Schema.EntityContainer.EntitySet;
143
- if (!isEntitySetPresent) {
144
- throw new Error(messages.MISSING_ENTITY_SETS);
145
- }
146
- return isEntitySetPresent;
147
- }
148
-
149
128
  function _isValidEDMXProvided(jsonObj) {
150
129
  let isValid = false;
151
130
  if (_isValidEDMX(jsonObj)) {
@@ -159,8 +138,7 @@ function _isValidEDMXProvided(jsonObj) {
159
138
  function _validateEDMX(jsonObj) {
160
139
  return (
161
140
  _isValidEDMXProvided(jsonObj) &&
162
- _hasEntityContainer(jsonObj) &&
163
- _hasEntitySet(jsonObj)
141
+ _hasEntityContainer(jsonObj)
164
142
  );
165
143
  }
166
144
 
@@ -184,54 +162,51 @@ function _getServiceNameSpace(jsonObj) {
184
162
  return null;
185
163
  }
186
164
 
187
- function _extractAssociationSet(associationSet) {
165
+ function _extractAssociationSet(associationSet, parserContext) {
188
166
  let associations = {};
189
167
  Object.keys(associationSet).forEach((key) => {
190
168
  if (key === "_attributes") {
191
169
  associations.Name = associationSet[key].Name;
192
170
  associations.End = associationSet.End;
193
- // allAssociationSets[associationSet[key]['Association']] = associationSet['End'];
194
- allAssociationSets[associationSet[key].Association] = associations;
171
+ parserContext.allAssociationSets[associationSet[key].Association] = associations;
195
172
  }
196
173
  });
197
174
  }
198
175
 
199
- function _extractAllAssociationSets(associationSets) {
200
- let i;
176
+ function _extractAllAssociationSets(associationSets, parserContext) {
201
177
  if (associationSets.length) {
202
178
  // Has many association sets in metadata
203
- for (i = 0; i < associationSets.length; i++) {
204
- _extractAssociationSet(associationSets[i]);
179
+ for (let i = 0; i < associationSets.length; i++) {
180
+ _extractAssociationSet(associationSets[i], parserContext);
205
181
  }
206
182
  } else {
207
183
  // Has only one association set in metadata
208
- _extractAssociationSet(associationSets);
184
+ _extractAssociationSet(associationSets, parserContext);
209
185
  }
210
186
  }
211
187
 
212
- function _extractAssociation(association) {
188
+ function _extractAssociation(association, parserContext) {
213
189
  Object.keys(association).forEach((key) => {
214
190
  if (key === "_attributes") {
215
- allAssociations[association[key].Name] = association;
191
+ parserContext.allAssociations[association[key].Name] = association;
216
192
  }
217
193
  });
218
194
  }
219
195
 
220
- function _extractAllAssociations(associations) {
221
- let i;
196
+ function _extractAllAssociations(associations, parserContext) {
222
197
  if (associations.length) {
223
198
  // Has many associations in metadata
224
- for (i = 0; i < associations.length; i++) {
225
- _extractAssociation(associations[i]);
199
+ for (let i = 0; i < associations.length; i++) {
200
+ _extractAssociation(associations[i], parserContext);
226
201
  }
227
202
  } else {
228
203
  // Has only one association in metadata
229
- _extractAssociation(associations);
204
+ _extractAssociation(associations, parserContext);
230
205
  }
231
206
  }
232
207
 
233
208
  function _extractEntityFromNamespace(entityName) {
234
- if (!entityName)
209
+ if (!entityName)
235
210
  return;
236
211
  let entityId = "";
237
212
  let pos = entityName.lastIndexOf(".");
@@ -242,71 +217,55 @@ function _extractEntityFromNamespace(entityName) {
242
217
  return entityId;
243
218
  }
244
219
 
245
- function _extractEntityFromEntitySet(entitySet) {
220
+ function _extractEntityFromEntitySet(entitySet, parserContext) {
246
221
  let entityName;
247
222
  Object.keys(entitySet).forEach((key) => {
248
223
  if (key === "_attributes") {
249
- allEntitySetMap[entitySet[key].Name] = entitySet[key].EntityType;
250
- if (allEntitySetMapMC[entitySet[key].EntityType] === undefined)
251
- allEntitySetMapMC[entitySet[key].EntityType] = [];
252
- allEntitySetMapMC[entitySet[key].EntityType].push(entitySet[key].Name);
224
+ parserContext.allEntitySetMap[entitySet[key].Name] = entitySet[key].EntityType;
225
+ if (parserContext.allEntitySetMapMC[entitySet[key].EntityType] === undefined)
226
+ parserContext.allEntitySetMapMC[entitySet[key].EntityType] = [];
227
+ parserContext.allEntitySetMapMC[entitySet[key].EntityType].push(entitySet[key].Name);
253
228
  entityName = _extractEntityFromNamespace(entitySet[key].EntityType);
254
- let namespaces = namespaceAttributeFilter(entitySet[key]);
255
- if(namespaces.length)
256
- allEntitySetNamespaces[entitySet[key].Name] = namespaces;
257
- allEntities.push(entityName);
258
- allEntitiesMC.push(entitySet[key].Name);
229
+ let namespaces = namespaceAttributeFilter(entitySet[key], parserContext);
230
+ if (namespaces.length)
231
+ parserContext.allEntitySetNamespaces[entitySet[key].Name] = namespaces;
232
+ parserContext.allEntities.push(entityName);
233
+ parserContext.allEntitiesMC.push(entitySet[key].Name);
259
234
  }
260
235
  });
261
236
  }
262
237
 
263
- function _extractAllEntityFromEntitySets(entitySets) {
264
- let i;
238
+ function _extractAllEntityFromEntitySets(entitySets, parserContext) {
265
239
  if (entitySets.length) {
266
240
  // Has many entity sets in metadata
267
- for (i = 0; i < entitySets.length; i++) {
268
- _extractEntityFromEntitySet(entitySets[i]);
241
+ for (let i = 0; i < entitySets.length; i++) {
242
+ _extractEntityFromEntitySet(entitySets[i], parserContext);
269
243
  }
270
244
  } else {
271
245
  // Has only one entity sets in metadata
272
- _extractEntityFromEntitySet(entitySets);
273
- }
274
- }
275
-
276
- function _extractNameFromFunctionImport(entityName) {
277
- let entityId = "";
278
- let pos = entityName.lastIndexOf("_");
279
- if (pos < 0) {
280
- return entityName;
246
+ _extractEntityFromEntitySet(entitySets, parserContext);
281
247
  }
282
- entityId = entityName.substring(pos + 1);
283
- return entityId;
284
248
  }
285
249
 
286
- function _getFunctionAttributes(functionImport, serviceNamespaceParam)
287
- {
250
+ function _getFunctionAttributes(functionImport, serviceNamespaceParam) {
288
251
  let funcAttributes = [];
289
- if(functionImport["_attributes"])
290
- {
291
- funcAttributes.push(serviceNamespaceParam + _extractNameFromFunctionImport(functionImport["_attributes"].Name));
252
+ if (functionImport["_attributes"]) {
253
+ funcAttributes.push(serviceNamespaceParam + functionImport["_attributes"].Name);
292
254
  funcAttributes.push(functionImport["_attributes"]["m:HttpMethod"]);
293
- if(functionImport["_attributes"].ReturnType)
294
- {
255
+ if (functionImport["_attributes"].ReturnType) {
295
256
  funcAttributes.push(functionImport["_attributes"].ReturnType);
296
257
  } else {
297
258
  funcAttributes.push(-1);
298
259
  }
299
260
  }
300
261
 
301
- if(functionImport["Parameter"])
302
- {
262
+ if (functionImport["Parameter"]) {
303
263
  funcAttributes.push(functionImport["Parameter"]);
304
264
  } else {
305
265
  funcAttributes.push(-1);
306
266
  }
307
267
 
308
- if(functionImport["Documentation"])
309
- {
268
+ if (functionImport["Documentation"]) {
310
269
  funcAttributes.push(_parseDocumentationTag(functionImport["Documentation"]));
311
270
  } else {
312
271
  funcAttributes.push(-1);
@@ -315,47 +274,45 @@ function _getFunctionAttributes(functionImport, serviceNamespaceParam)
315
274
  return funcAttributes;
316
275
  }
317
276
 
318
- function _extractFunctionImport(functionImport, serviceNamespaceParam)
319
- {
277
+ function _extractFunctionImport(functionImport, parserContext) {
320
278
  //extracting the bounded and unbounded function import
321
279
  let boundedFunctionImports = [];
322
280
  let entityName;
323
281
  Object.keys(functionImport).forEach((key) => {
324
- if(key === "_attributes") {
325
- if(functionImport[key]["sap:action-for"])
326
- {
282
+ if (key === "_attributes") {
283
+ if (functionImport[key]["sap:action-for"]) {
327
284
  //storing bounded function imports
328
285
  entityName = _extractEntityFromNamespace(functionImport[key]["sap:action-for"]);
329
- boundedFunctionImports = (allFunctionImportsMap[entityName]) ? allFunctionImportsMap[entityName] : [];
330
- boundedFunctionImports.push(_getFunctionAttributes(functionImport,""));
331
- allFunctionImportsMap[entityName] = boundedFunctionImports;
286
+ boundedFunctionImports = (parserContext.allFunctionImportsMap[entityName])
287
+ ? parserContext.allFunctionImportsMap[entityName] : [];
288
+ boundedFunctionImports.push(_getFunctionAttributes(functionImport, ""));
289
+ parserContext.allFunctionImportsMap[entityName] = boundedFunctionImports;
332
290
  }
333
- else
334
- {
291
+ else {
335
292
  //storing unbounded function imports
336
- allFunctionImports.push(_getFunctionAttributes(functionImport,serviceNamespaceParam + "."));
293
+ parserContext.allFunctionImports.push(
294
+ _getFunctionAttributes(functionImport, parserContext.serviceNamespace + ".")
295
+ );
337
296
  }
338
297
  }
339
298
  });
340
299
  }
341
300
 
342
301
  //extracting the function imports from the metadata
343
- function _extractAllFunctionImports(functionImports, serviceNamespaceParam)
344
- {
345
- let i;
302
+ function _extractAllFunctionImports(functionImports, parserContext) {
346
303
  if (functionImports.length) {
347
304
  //Has many function imports in metadata
348
- for (i = 0; i < functionImports.length; i++) {
349
- _extractFunctionImport(functionImports[i], serviceNamespaceParam);
305
+ for (let i = 0; i < functionImports.length; i++) {
306
+ _extractFunctionImport(functionImports[i], parserContext);
350
307
  }
351
308
  } else {
352
309
  //Has only one function import in metadata
353
- _extractFunctionImport(functionImports, serviceNamespaceParam);
310
+ _extractFunctionImport(functionImports, parserContext);
354
311
  }
355
312
  }
356
313
 
357
314
  function _replaceSpecialCharacters(text) {
358
- return text.replace(/(?:\\[rn]|[\r\n]+)+/gm, "\\n").replace(/\s+/g, ' ').replace(/"/g, "&quot;").trim();
315
+ return text.replace(/(?:\\[rn]|[\r\n]+)+/gm, "\\n").replace(/\s+/g, ' ').replace(/"/g, "&quot;").trim();
359
316
  }
360
317
 
361
318
  // to parse the documentation tag
@@ -363,7 +320,7 @@ function _parseDocumentationTag(documentedContent) {
363
320
  let documentation = "";
364
321
  if (documentedContent.Summary && documentedContent.Summary._text) {
365
322
  documentation = _replaceSpecialCharacters(documentedContent.Summary._text);
366
- }
323
+ }
367
324
  if (documentedContent.LongDescription && documentedContent.LongDescription._text) {
368
325
  if (documentedContent.Summary)
369
326
  documentation += "\\n\\n";
@@ -372,42 +329,40 @@ function _parseDocumentationTag(documentedContent) {
372
329
  return documentation;
373
330
  }
374
331
 
375
- function _extractComplexType(complexType, serviceNamespaceParam) {
332
+ function _extractComplexType(complexType, parserContext) {
376
333
  let complexTypeKey = "";
377
334
  let baseType = "";
378
335
  let properties;
379
336
  let namespaceAttributes = {};
380
337
  Object.keys(complexType).forEach((key) => {
381
338
  if (key === "_attributes") {
382
- complexTypeKey =
383
- serviceNamespaceParam + "." + complexType[key].Name;
384
- namespaceAttributes = namespaceAttributeFilter(complexType[key]);
339
+ complexTypeKey = parserContext.serviceNamespace + "." + complexType[key].Name;
340
+ namespaceAttributes = namespaceAttributeFilter(complexType[key], parserContext);
385
341
  baseType = complexType[key].BaseType;
386
342
  } else if (key === "Property") {
387
343
  properties = complexType.Property;
388
344
  } else if (key === "Documentation") {
389
- allComplexTypeDocs[complexTypeKey] = _parseDocumentationTag(complexType.Documentation);
345
+ parserContext.allComplexTypeDocs[complexTypeKey] = _parseDocumentationTag(complexType.Documentation);
390
346
  }
391
347
  });
392
- allComplexTypes[complexTypeKey] = properties;
348
+ parserContext.allComplexTypes[complexTypeKey] = properties;
393
349
  if (complexTypeKey && baseType) {
394
- allInheritedComplexTypes[complexTypeKey] = baseType;
350
+ parserContext.allInheritedComplexTypes[complexTypeKey] = baseType;
395
351
  }
396
352
  if (namespaceAttributes.length) {
397
- allComplexTypeNamespaces[complexTypeKey] = namespaceAttributes;
353
+ parserContext.allComplexTypeNamespaces[complexTypeKey] = namespaceAttributes;
398
354
  }
399
355
  }
400
356
 
401
- function _extractAllComplexTypes(complexTypes, serviceNamespaceParam) {
402
- let i;
357
+ function _extractAllComplexTypes(complexTypes, parserContext) {
403
358
  if (complexTypes.length) {
404
359
  // Has many complex types in metadata
405
- for (i = 0; i < complexTypes.length; i++) {
406
- _extractComplexType(complexTypes[i], serviceNamespaceParam);
360
+ for (let i = 0; i < complexTypes.length; i++) {
361
+ _extractComplexType(complexTypes[i], parserContext);
407
362
  }
408
363
  } else {
409
364
  // Has only one association in metadata
410
- _extractComplexType(complexTypes, serviceNamespaceParam);
365
+ _extractComplexType(complexTypes, parserContext);
411
366
  }
412
367
  }
413
368
 
@@ -420,13 +375,13 @@ function _getServiceEntityProperty(
420
375
  displayFormat,
421
376
  isKey,
422
377
  documentation,
423
- allowedNamespaceAttributes = -1
378
+ allowedNamespaceAttributes = -1,
379
+ parserContext
424
380
  ) {
425
381
  let isCollection = -1;
426
382
  //preprocessing of datatype in case it is a collection
427
- if(dataType.substring(0,10) === 'Collection')
428
- {
429
- dataType = dataType.substring(11,dataType.length-1);
383
+ if (dataType.substring(0, 10) === 'Collection') {
384
+ dataType = dataType.substring(11, dataType.length - 1);
430
385
  isCollection = 1;
431
386
  }
432
387
 
@@ -437,7 +392,7 @@ function _getServiceEntityProperty(
437
392
 
438
393
  let cdsDataType = null;
439
394
  let hasInvalidPrecision = false;
440
- let propertyJson='';
395
+ let propertyJson = '';
441
396
  if (length && length > 0) {
442
397
  cdsDataType = edmxncdsdatatype[dataType + "_m"];
443
398
  } else if (precision && precision > 0) {
@@ -459,27 +414,26 @@ function _getServiceEntityProperty(
459
414
  cdsDataType = edmxncdsdatatype[dataType + "_a"];
460
415
  }
461
416
  // Lookup from complex type properties
462
- if (!cdsDataType && allComplexTypes[dataType]) {
417
+ if (!cdsDataType && parserContext.allComplexTypes[dataType]) {
463
418
  cdsDataType = dataType;
464
419
  }
465
420
 
466
421
  // Lookup from inherited complex type properties
467
- if (!cdsDataType && allInheritedComplexTypes[dataType]) {
422
+ if (!cdsDataType && parserContext.allInheritedComplexTypes[dataType]) {
468
423
  cdsDataType = dataType;
469
424
  }
470
425
 
471
426
  //Possibility of entity type or entity set as the data type
472
- if (!cdsDataType && allEntitySetMapMC[dataType]) {
473
- cdsDataType = serviceNamespace + "." + allEntitySetMapMC[dataType][0];
474
- } else if(!cdsDataType && allEntitySetMap[_extractEntityFromNamespace(dataType)]) {
427
+ if (!cdsDataType && parserContext.allEntitySetMapMC[dataType]) {
428
+ cdsDataType = parserContext.serviceNamespace + "." + parserContext.allEntitySetMapMC[dataType][0];
429
+ } else if (!cdsDataType && parserContext.allEntitySetMap[_extractEntityFromNamespace(dataType)]) {
475
430
  cdsDataType = dataType;
476
431
  }
477
432
 
478
433
  //if the cdsDataType is undefined/ not supported
479
- if(cdsDataType === undefined)
480
- {
481
- let message = '"' + dataType + '" is not supported';
482
- if(propertyName)
434
+ if (cdsDataType === undefined) {
435
+ let message = '"' + dataType + '" is not supported';
436
+ if (propertyName)
483
437
  message += ' (in element:"' + propertyName + '")';
484
438
  else
485
439
  message += ' (in return type)'
@@ -487,22 +441,23 @@ function _getServiceEntityProperty(
487
441
  return "";
488
442
  }
489
443
 
490
- if(propertyName)
444
+ if (propertyName)
491
445
  propertyJson = '"' + propertyName + '": {\n';
492
446
 
493
447
  if (isKey) {
494
448
  propertyJson = propertyJson + '"key": true,\n';
495
449
  }
496
- if(isCollection === 1)
497
- {
450
+ if (isCollection === 1) {
498
451
  propertyJson = propertyJson + '"items": { \n'
499
452
  }
500
453
  propertyJson = propertyJson + '"type":"' + cdsDataType + '"';
501
454
 
502
455
  //if annotations to be added
503
- if(edmxncdsdatatype[dataType + "_a"] && cdsDataType != "cds.Date")
504
- {
505
- propertyJson = propertyJson + ',\n"@odata.type": "' + dataType + '"';
456
+ if (edmxncdsdatatype[dataType + "_a"] && cdsDataType != "cds.Date") {
457
+ if (dataType === 'Edm.Stream')
458
+ propertyJson = propertyJson + ',\n"@Core.MediaType": "application/octet-stream"';
459
+ else
460
+ propertyJson = propertyJson + ',\n"@odata.Type": "' + dataType + '"';
506
461
  }
507
462
 
508
463
  if (length && length > 0) {
@@ -515,19 +470,17 @@ function _getServiceEntityProperty(
515
470
  propertyJson = propertyJson + ',\n"scale":' + 0;
516
471
  }
517
472
  }
518
-
473
+
519
474
  //adding precision in case of DateTime datatypes
520
- if((dataType === "Edm.DateTimeOffset" || dataType === "Edm.DateTime") && cdsDataType != "cds.Date")
521
- {
522
- if(!precision || precision === -1) precision = 0;
523
- propertyJson = propertyJson + ',\n"@odata.precision": ' + precision;
475
+ if ((dataType === "Edm.DateTimeOffset" || dataType === "Edm.DateTime") && cdsDataType != "cds.Date") {
476
+ if (!precision || precision === -1) precision = 0;
477
+ propertyJson = propertyJson + ',\n"@odata.Precision": ' + precision;
524
478
  }
525
479
 
526
- if(isCollection === 1)
527
- {
480
+ if (isCollection === 1) {
528
481
  propertyJson = propertyJson + '\n}'
529
482
  }
530
- if(documentation != -1 && documentation){
483
+ if (documentation != -1 && documentation) {
531
484
  propertyJson = propertyJson + ',\n"doc":"' + documentation + '"';
532
485
  }
533
486
 
@@ -535,33 +488,33 @@ function _getServiceEntityProperty(
535
488
  propertyJson += _generateNamespaceAttributes(allowedNamespaceAttributes, true);
536
489
  }
537
490
 
538
- if(propertyName)
491
+ if (propertyName)
539
492
  propertyJson = propertyJson + "\n}";
540
493
  return propertyJson;
541
494
  }
542
495
 
543
- function _getServiceComplexType(complexTypeKey, complexType) {
496
+ function _getServiceComplexType(complexTypeKey, complexType, parserContext) {
544
497
  let complexTypeCSN = '"' + complexTypeKey + '": {\n';
545
498
  let complexTypeProperty;
546
499
  let i;
547
500
  complexTypeCSN = complexTypeCSN + '"kind": "type",\n';
548
- if(allComplexTypeNamespaces[complexTypeKey]) {
549
- complexTypeCSN += _generateNamespaceAttributes(allComplexTypeNamespaces[complexTypeKey], false);
501
+ if (parserContext.allComplexTypeNamespaces[complexTypeKey]) {
502
+ complexTypeCSN += _generateNamespaceAttributes(parserContext.allComplexTypeNamespaces[complexTypeKey], false);
550
503
  }
551
- if (allComplexTypeDocs[complexTypeKey])
552
- complexTypeCSN = complexTypeCSN + '"doc":' + `"${allComplexTypeDocs[complexTypeKey]}",` + "\n";
504
+ if (parserContext.allComplexTypeDocs[complexTypeKey])
505
+ complexTypeCSN = complexTypeCSN + '"doc":' + `"${parserContext.allComplexTypeDocs[complexTypeKey]}",` + "\n";
553
506
  complexTypeCSN = complexTypeCSN + '"elements": {\n';
554
507
  if (complexType) {
555
508
  if (complexType.length) {
556
509
  // More than one complex types
557
510
  for (i = 0; i < complexType.length; i++) {
558
511
  complexTypeProperty = complexType[i]._attributes;
559
- if(complexType[i].Documentation)
512
+ if (complexType[i].Documentation)
560
513
  complexTypeProperty.doc = _parseDocumentationTag(complexType[i].Documentation);
561
- let namespaceAttributes = namespaceAttributeFilter(complexTypeProperty)
514
+ let namespaceAttributes = namespaceAttributeFilter(complexTypeProperty, parserContext);
562
515
  const complexTypePropertyNamespace = namespaceAttributes.length ? namespaceAttributes : -1
563
-
564
- let complexProperty =
516
+
517
+ let complexProperty =
565
518
  _getServiceEntityProperty(
566
519
  complexTypeProperty.Name,
567
520
  complexTypeProperty.Type,
@@ -571,7 +524,8 @@ function _getServiceComplexType(complexTypeKey, complexType) {
571
524
  complexTypeProperty["sap:display-format"],
572
525
  false,
573
526
  complexTypeProperty.doc,
574
- complexTypePropertyNamespace
527
+ complexTypePropertyNamespace,
528
+ parserContext
575
529
  );
576
530
  complexTypeCSN = complexTypeCSN + complexProperty;
577
531
  if (i !== complexType.length - 1 && complexProperty != "") {
@@ -583,14 +537,13 @@ function _getServiceComplexType(complexTypeKey, complexType) {
583
537
  } else {
584
538
  // Only one complex type
585
539
  complexTypeProperty = complexType._attributes;
586
- if(complexType.Documentation)
540
+ if (complexType.Documentation)
587
541
  complexTypeProperty.doc = _parseDocumentationTag(complexType.Documentation);
588
542
 
589
- let namespaceAttributes = namespaceAttributeFilter(complexTypeProperty);
543
+ let namespaceAttributes = namespaceAttributeFilter(complexTypeProperty, parserContext);
590
544
  const complexTypePropertyNamespace = namespaceAttributes.length ? namespaceAttributes : -1;
591
-
592
- complexTypeCSN =
593
- complexTypeCSN +
545
+
546
+ complexTypeCSN = complexTypeCSN +
594
547
  _getServiceEntityProperty(
595
548
  complexTypeProperty.Name,
596
549
  complexTypeProperty.Type,
@@ -600,7 +553,8 @@ function _getServiceComplexType(complexTypeKey, complexType) {
600
553
  complexTypeProperty["sap:display-format"],
601
554
  false,
602
555
  complexTypeProperty.doc,
603
- complexTypePropertyNamespace
556
+ complexTypePropertyNamespace,
557
+ parserContext
604
558
  );
605
559
  }
606
560
 
@@ -609,30 +563,24 @@ function _getServiceComplexType(complexTypeKey, complexType) {
609
563
  }
610
564
  }
611
565
  complexTypeCSN = complexTypeCSN + "}\n";
612
- if (allInheritedComplexTypes[complexTypeKey]) {
566
+ if (parserContext.allInheritedComplexTypes[complexTypeKey]) {
613
567
  complexTypeCSN = complexTypeCSN + ",\n";
614
- complexTypeCSN =
615
- complexTypeCSN +
616
- '"includes": ["' +
617
- allInheritedComplexTypes[complexTypeKey] +
618
- '"]\n';
568
+ complexTypeCSN = complexTypeCSN +
569
+ '"includes": ["' + parserContext.allInheritedComplexTypes[complexTypeKey] + '"]\n';
619
570
  }
620
571
  complexTypeCSN = complexTypeCSN + "}\n";
621
572
  return complexTypeCSN;
622
573
  }
623
574
 
624
- function _getServiceComplexTypes() {
575
+ function _getServiceComplexTypes(parserContext) {
625
576
  let complexTypeCSN = "";
626
- let complexTypesKeys = Object.keys(allComplexTypes);
627
- let i;
577
+ let complexTypesKeys = Object.keys(parserContext.allComplexTypes);
628
578
  let complexTypeKey;
629
579
  let complexType;
630
- for (i = 0; i < complexTypesKeys.length; i++) {
580
+ for (let i = 0; i < complexTypesKeys.length; i++) {
631
581
  complexTypeKey = complexTypesKeys[i];
632
- complexType = allComplexTypes[complexTypesKeys[i]];
633
- complexTypeCSN =
634
- complexTypeCSN +
635
- _getServiceComplexType(complexTypeKey, complexType);
582
+ complexType = parserContext.allComplexTypes[complexTypesKeys[i]];
583
+ complexTypeCSN = complexTypeCSN + _getServiceComplexType(complexTypeKey, complexType, parserContext);
636
584
  if (i !== complexTypesKeys.length - 1) {
637
585
  complexTypeCSN = complexTypeCSN + ",\n";
638
586
  } else {
@@ -642,47 +590,49 @@ function _getServiceComplexTypes() {
642
590
  return complexTypeCSN;
643
591
  }
644
592
 
645
- function _parseParameter(parameter)
646
- {
593
+ function _parseParameter(parameter, parserContext) {
647
594
  let csn = "";
648
595
  let doc;
649
- if(parameter.Documentation)
596
+ if (parameter.Documentation)
650
597
  doc = _parseDocumentationTag(parameter.Documentation);
651
598
 
652
- let namespaceAttributes = namespaceAttributeFilter(parameter._attributes);
599
+ let namespaceAttributes = namespaceAttributeFilter(parameter._attributes, parserContext);
653
600
  const parameterNamespaceAttributes = namespaceAttributes.length ? namespaceAttributes : -1;
654
601
 
655
- csn = csn + _getServiceEntityProperty(parameter["_attributes"].Name,
656
- parameter["_attributes"].Type,
657
- parameter["_attributes"].MaxLength,
658
- parameter["_attributes"].Precision,
659
- parameter["_attributes"].Scale,
660
- parameter["_attributes"]["sap:display-format"],
661
- false,
662
- doc,
663
- parameterNamespaceAttributes);
602
+ csn = csn +
603
+ _getServiceEntityProperty(
604
+ parameter["_attributes"].Name,
605
+ parameter["_attributes"].Type,
606
+ parameter["_attributes"].MaxLength,
607
+ parameter["_attributes"].Precision,
608
+ parameter["_attributes"].Scale,
609
+ parameter["_attributes"]["sap:display-format"],
610
+ false,
611
+ doc,
612
+ parameterNamespaceAttributes,
613
+ parserContext
614
+ );
664
615
  return csn;
665
616
  }
666
617
 
667
- function _checkParameterKey(parameter, entityKeysList){
668
- if ( entityKeysList && (Object.values(entityKeysList).indexOf(parameter._attributes.Name) > -1)){
618
+ function _checkParameterKey(parameter, entityKeysList) {
619
+ if (entityKeysList && (Object.values(entityKeysList).indexOf(parameter._attributes.Name) > -1)) {
669
620
  return true;
670
621
  }
671
- return false;
622
+ return false;
672
623
  }
673
624
 
674
- function _parseParametersFunctionImport(parameters, isBounded, entityKeysList) {
625
+ function _parseParametersFunctionImport(parameters, entityKeysList, parserContext) {
675
626
  let csn = "";
676
627
  let parameterCsn = "";
677
- let i = 0;
678
- if(parameters.length)
679
- {
680
- for (i; i < parameters.length; i++) {
628
+
629
+ if (parameters.length) {
630
+ for (let i = 0; i < parameters.length; i++) {
681
631
  // check if the parameter is a key of the entity type or not
682
632
  // If yes then that paramater is ignored in CSN
683
633
  let isKey = _checkParameterKey(parameters[i], entityKeysList);
684
634
  if (isKey == false) {
685
- parameterCsn = _parseParameter(parameters[i]);
635
+ parameterCsn = _parseParameter(parameters[i], parserContext);
686
636
  csn = csn + parameterCsn;
687
637
  if (i !== parameters.length - 1 && parameterCsn != "") {
688
638
  csn = csn + ",\n";
@@ -694,40 +644,36 @@ function _parseParametersFunctionImport(parameters, isBounded, entityKeysList)
694
644
  } else {
695
645
  let isKey = _checkParameterKey(parameters);
696
646
  if (isKey === false) {
697
- csn = csn + _parseParameter(parameters);
647
+ csn = csn + _parseParameter(parameters, parserContext);
698
648
  }
699
649
  }
700
650
 
701
651
  if (csn && (csn.endsWith(",\n") || csn.endsWith(",\n\n"))) {
702
- csn= csn.substring(0, csn.lastIndexOf(",\n")) + "\n";
652
+ csn = csn.substring(0, csn.lastIndexOf(",\n")) + "\n";
703
653
  }
704
654
  return csn;
705
655
  }
706
656
 
707
- function _getFunctionImport(functionImport,isBounded,entityKeysList) {
657
+ function _getFunctionImport(functionImport, isBounded, entityKeysList, parserContext) {
708
658
  let noValue;
709
659
  let csn = "";
710
660
  csn = csn + '"' + functionImport[0] + '": { \n';
711
661
  csn = csn + '"kind": "';
712
- if(functionImport[1] === "GET")
713
- {
662
+ if (functionImport[1] === "GET") {
714
663
  csn = csn + "function";
715
- } else if(functionImport[1] === "POST")
716
- {
664
+ } else if (functionImport[1] === "POST") {
717
665
  csn = csn + "action";
718
666
  } else {
719
- let message = functionImport[0].substring(functionImport[0].lastIndexOf(".") + 1) + " has kind " + functionImport[1] + " which is not supported.";
667
+ let message = functionImport[0].substring(functionImport[0].lastIndexOf(".") + 1) + " has kind " +
668
+ functionImport[1] + " which is not supported.";
720
669
  console.log(warn(message));
721
670
  return "";
722
671
  }
723
672
  csn = csn + '"';
724
- if(functionImport[3] !== -1)
725
- {
726
- if(isBounded === 0 || (isBounded === 1 && functionImport[3] instanceof Array ))
727
- {
728
- let parametersCsn = _parseParametersFunctionImport(functionImport[3],isBounded,entityKeysList);
729
- if(parametersCsn != "")
730
- {
673
+ if (functionImport[3] !== -1) {
674
+ if (isBounded === 0 || (isBounded === 1 && functionImport[3] instanceof Array)) {
675
+ let parametersCsn = _parseParametersFunctionImport(functionImport[3], entityKeysList, parserContext);
676
+ if (parametersCsn != "") {
731
677
  csn = csn + ", \n";
732
678
  csn = csn + '"params": { \n';
733
679
  csn = csn + parametersCsn;
@@ -735,11 +681,10 @@ function _getFunctionImport(functionImport,isBounded,entityKeysList) {
735
681
  }
736
682
  }
737
683
  }
738
- if(functionImport[2] !== -1)
739
- {
740
- let returnCsn = _getServiceEntityProperty(noValue,functionImport[2],noValue,noValue,noValue,noValue,noValue,noValue);
741
- if(returnCsn != "")
742
- {
684
+ if (functionImport[2] !== -1) {
685
+ let returnCsn = _getServiceEntityProperty(noValue, functionImport[2], noValue, noValue, noValue,
686
+ noValue, noValue, noValue, -1, parserContext);
687
+ if (returnCsn != "") {
743
688
  csn = csn + ", \n";
744
689
  csn = csn + '"returns": { \n';
745
690
  //return type
@@ -747,8 +692,7 @@ function _getFunctionImport(functionImport,isBounded,entityKeysList) {
747
692
  csn = csn + '\n }';
748
693
  }
749
694
  }
750
- if(functionImport[4] !== -1 && functionImport[4])
751
- {
695
+ if (functionImport[4] !== -1 && functionImport[4]) {
752
696
  csn = csn + ',\n "doc": "' + _replaceSpecialCharacters(functionImport[4]) + '"';
753
697
  }
754
698
 
@@ -756,15 +700,14 @@ function _getFunctionImport(functionImport,isBounded,entityKeysList) {
756
700
  return csn;
757
701
  }
758
702
 
759
- function _getAllFunctionImports(functionImports,isBounded,entityKeysList) {
703
+ function _getAllFunctionImports(functionImports, isBounded, entityKeysList, parserContext) {
760
704
  let functionImportsCSN = "";
761
705
  let i;
762
706
  let functionImportCSN = "";
763
- for(i=0; i<functionImports.length;i++)
764
- {
765
- functionImportCSN = _getFunctionImport(functionImports[i],isBounded, entityKeysList);
707
+ for (i = 0; i < functionImports.length; i++) {
708
+ functionImportCSN = _getFunctionImport(functionImports[i], isBounded, entityKeysList, parserContext);
766
709
  functionImportsCSN = functionImportsCSN + functionImportCSN;
767
- if(i!== functionImports.length - 1 && functionImportCSN !== "" ) {
710
+ if (i !== functionImports.length - 1 && functionImportCSN !== "") {
768
711
  functionImportsCSN = functionImportsCSN + ",\n";
769
712
  } else {
770
713
  functionImportsCSN = functionImportsCSN + "\n";
@@ -773,7 +716,7 @@ function _getAllFunctionImports(functionImports,isBounded,entityKeysList) {
773
716
 
774
717
  //if last function import is omitted, remove the extra characters
775
718
  if (functionImportsCSN && (functionImportsCSN.endsWith(",\n") || functionImportsCSN.endsWith(",\n\n"))) {
776
- functionImportsCSN= functionImportsCSN.substring(0, functionImportsCSN.lastIndexOf(",\n")) + "\n";
719
+ functionImportsCSN = functionImportsCSN.substring(0, functionImportsCSN.lastIndexOf(",\n")) + "\n";
777
720
  }
778
721
  return functionImportsCSN;
779
722
  }
@@ -782,13 +725,13 @@ function _getEntityName(entity) {
782
725
  return entity._attributes.Name;
783
726
  }
784
727
 
785
- function _parseEntityAttributes(attributes) {
728
+ function _parseEntityAttributes(attributes, parserContext) {
786
729
  let entityAttributes = {};
787
730
  // Extract only needed entity attributes
788
731
  entityAttributes.Name = attributes.Name;
789
732
  entityAttributes.BaseType = attributes.BaseType;
790
733
  entityAttributes.Abstract = attributes.Abstract;
791
- entityAttributes.allowedNamespaceAttributes = namespaceAttributeFilter(attributes);
734
+ entityAttributes.allowedNamespaceAttributes = namespaceAttributeFilter(attributes, parserContext);
792
735
 
793
736
  return entityAttributes;
794
737
  }
@@ -809,10 +752,10 @@ function _parseEntityKeys(keys) {
809
752
  return retKeys;
810
753
  }
811
754
 
812
- function _getPropertyAttributes(propAttributes) {
755
+ function _getPropertyAttributes(propAttributes, parserContext) {
813
756
  let propOthers = [];
814
757
 
815
- let namespaceAttributes = namespaceAttributeFilter(propAttributes)
758
+ let namespaceAttributes = namespaceAttributeFilter(propAttributes, parserContext)
816
759
 
817
760
  propOthers.push(propAttributes.Type);
818
761
  if (propAttributes.MaxLength) {
@@ -838,9 +781,9 @@ function _getPropertyAttributes(propAttributes) {
838
781
  propOthers.push(-1);
839
782
  }
840
783
 
841
- if(propAttributes.doc){
784
+ if (propAttributes.doc) {
842
785
  propOthers.push(propAttributes.doc.replace(/"/g, '&quot;'));
843
- }else{
786
+ } else {
844
787
  propOthers.push(-1);
845
788
  }
846
789
 
@@ -853,26 +796,26 @@ function _getPropertyAttributes(propAttributes) {
853
796
  return propOthers;
854
797
  }
855
798
 
856
- function _parseEntityProperty(properties) {
799
+ function _parseEntityProperty(properties, parserContext) {
857
800
  let propAttributes;
858
801
  let retProperties = {};
859
- let i;
802
+
860
803
  if (properties.length) {
861
804
  // Has more than one entities
862
- for (i = 0; i < properties.length; i++) {
805
+ for (let i = 0; i < properties.length; i++) {
863
806
  propAttributes = properties[i]._attributes;
864
807
  // if the property contains documentatin tag
865
- if(properties[i] && properties[i].Documentation)
808
+ if (properties[i] && properties[i].Documentation)
866
809
  propAttributes.doc = _parseDocumentationTag(properties[i].Documentation);
867
- retProperties[propAttributes.Name] = _getPropertyAttributes(propAttributes);
810
+ retProperties[propAttributes.Name] = _getPropertyAttributes(propAttributes, parserContext);
868
811
  }
869
812
  } else {
870
813
  // Has only one entity
871
814
  propAttributes = properties._attributes;
872
815
  // if the property contains documentatin tag
873
- if(properties && properties.Documentation)
816
+ if (properties && properties.Documentation)
874
817
  propAttributes.doc = _parseDocumentationTag(properties.Documentation);
875
- retProperties[propAttributes.Name] = _getPropertyAttributes(propAttributes);
818
+ retProperties[propAttributes.Name] = _getPropertyAttributes(propAttributes, parserContext);
876
819
  }
877
820
  return retProperties;
878
821
  }
@@ -880,13 +823,13 @@ function _parseEntityProperty(properties) {
880
823
  function _parseNavigationProperty(navigationProperties) {
881
824
  let retNavProperties = {};
882
825
  let navPropAttributes;
883
- let i;
826
+
884
827
  if (navigationProperties.length) {
885
828
  // Has more than one navigation property
886
- for (i = 0; i < navigationProperties.length; i++) {
829
+ for (let i = 0; i < navigationProperties.length; i++) {
887
830
  navPropAttributes = navigationProperties[i]._attributes;
888
831
  // if the property contains documentatin tag
889
- if(navigationProperties[i] && navigationProperties[i].Documentation)
832
+ if (navigationProperties[i] && navigationProperties[i].Documentation)
890
833
  navPropAttributes.doc = _parseDocumentationTag(navigationProperties[i].Documentation);
891
834
  retNavProperties[navPropAttributes.Name] = navPropAttributes;
892
835
  }
@@ -894,18 +837,18 @@ function _parseNavigationProperty(navigationProperties) {
894
837
  // Has only one navigation property
895
838
  navPropAttributes = navigationProperties._attributes;
896
839
  // if the property contains documentatin tag
897
- if(navigationProperties && navigationProperties.Documentation)
840
+ if (navigationProperties && navigationProperties.Documentation)
898
841
  navPropAttributes.doc = _parseDocumentationTag(navigationProperties.Documentation);
899
842
  retNavProperties[navPropAttributes.Name] = navPropAttributes;
900
843
  }
901
844
  return retNavProperties;
902
845
  }
903
846
 
904
- function _generateCSNEntityKeys(entityKeysList, entityPropertiesMap) {
847
+ function _generateCSNEntityKeys(entityKeysList, entityPropertiesMap, parserContext) {
905
848
  let csnEntity = "";
906
849
  let propAttributes;
907
- let i;
908
- for (i = 0; i < entityKeysList.length; i++) {
850
+
851
+ for (let i = 0; i < entityKeysList.length; i++) {
909
852
  propAttributes = entityPropertiesMap[entityKeysList[i]];
910
853
  let keyCsn =
911
854
  _getServiceEntityProperty(
@@ -917,7 +860,8 @@ function _generateCSNEntityKeys(entityKeysList, entityPropertiesMap) {
917
860
  propAttributes[4],
918
861
  true,
919
862
  propAttributes[5],
920
- propAttributes[6]
863
+ propAttributes[6],
864
+ parserContext
921
865
  );
922
866
  csnEntity = csnEntity + keyCsn;
923
867
  if (i !== entityKeysList.length - 1 && keyCsn != "") {
@@ -925,15 +869,14 @@ function _generateCSNEntityKeys(entityKeysList, entityPropertiesMap) {
925
869
  }
926
870
  }
927
871
  if (csnEntity && (csnEntity.endsWith(",\n") || csnEntity.endsWith(",\n\n"))) {
928
- csnEntity= csnEntity.substring(0, csnEntity.lastIndexOf(",\n")) + "\n";
872
+ csnEntity = csnEntity.substring(0, csnEntity.lastIndexOf(",\n")) + "\n";
929
873
  }
930
874
  return csnEntity;
931
875
  }
932
876
 
933
- function _generateCSNEntityProperties(entityKeysList, entityPropertiesMap) {
877
+ function _generateCSNEntityProperties(entityKeysList, entityPropertiesMap, parserContext) {
934
878
  let csnEntity = "";
935
879
  let entityProperties = Object.keys(entityPropertiesMap);
936
- let i;
937
880
  let property;
938
881
  let propAttributes;
939
882
  if (entityKeysList.length > 0) {
@@ -943,7 +886,7 @@ function _generateCSNEntityProperties(entityKeysList, entityPropertiesMap) {
943
886
  csnEntity = csnEntity + "\n";
944
887
  }
945
888
  }
946
- for (i = 0; i < entityProperties.length; i++) {
889
+ for (let i = 0; i < entityProperties.length; i++) {
947
890
  property = entityProperties[i];
948
891
  // Include Property which are not part of keys
949
892
  if (entityKeysList.indexOf(property) === -1) {
@@ -958,7 +901,8 @@ function _generateCSNEntityProperties(entityKeysList, entityPropertiesMap) {
958
901
  propAttributes[4],
959
902
  false,
960
903
  propAttributes[5],
961
- propAttributes[6]
904
+ propAttributes[6],
905
+ parserContext
962
906
  );
963
907
  csnEntity = csnEntity + propertyString;
964
908
  if (i !== entityProperties.length - 1 && propertyString != "") {
@@ -970,35 +914,29 @@ function _generateCSNEntityProperties(entityKeysList, entityPropertiesMap) {
970
914
  }
971
915
  // Last property can be an key; eliminate additional delimiter.
972
916
  // Last property can have undefined datatype and be ignored too
973
- //doubt
974
917
  if (csnEntity && (csnEntity.endsWith(",\n") || csnEntity.endsWith(",\n\n"))) {
975
918
  csnEntity = csnEntity.substring(0, csnEntity.lastIndexOf(",\n")) + "\n";
976
919
  }
977
920
  return csnEntity;
978
921
  }
979
922
 
980
- function _getAssociatedEntity(associationEnds, toRole, mockServerUc) {
923
+ function _getAssociatedEntity(associationEnds, toRole, mockServerUc, parserContext) {
981
924
  let entityName;
982
925
  let entitySetName;
983
926
  Object.keys(associationEnds).forEach((i) => {
984
927
  if (toRole === associationEnds[i]._attributes.Role) {
985
928
  entitySetName = associationEnds[i]._attributes.EntitySet;
986
929
  if (mockServerUc) {
987
- entityName = serviceNamespace + "." + entitySetName;
930
+ entityName = parserContext.serviceNamespace + "." + entitySetName;
988
931
  } else {
989
- entityName = allEntitySetMap[entitySetName];
932
+ entityName = parserContext.allEntitySetMap[entitySetName];
990
933
  }
991
934
  }
992
935
  });
993
936
  return entityName;
994
937
  }
995
938
 
996
- function _getCSNMultiplicity(
997
- associationEnds,
998
- toRole,
999
- entityName,
1000
- mockServerUc
1001
- ) {
939
+ function _getCSNMultiplicity(associationEnds, toRole, entityName, mockServerUc, parserContext) {
1002
940
  let csn = "";
1003
941
  let multiplicity;
1004
942
  let attributes;
@@ -1007,8 +945,7 @@ function _getCSNMultiplicity(
1007
945
  if (!stop) {
1008
946
  attributes = associationEnds[i]._attributes;
1009
947
  if (mockServerUc) {
1010
- let entityNameWithOutNS =
1011
- allEntitySetMap[_extractEntityFromNamespace(entityName)];
948
+ let entityNameWithOutNS = parserContext.allEntitySetMap[_extractEntityFromNamespace(entityName)];
1012
949
  if (
1013
950
  toRole === attributes.Role &&
1014
951
  entityNameWithOutNS === attributes.Type
@@ -1058,11 +995,7 @@ function _getCSNRefrenentialCondition(navPropName, from, to) {
1058
995
  return csn;
1059
996
  }
1060
997
 
1061
- function _getCSNMultipleRefrenentialConditions(
1062
- refConstraints,
1063
- navPropName,
1064
- role
1065
- ) {
998
+ function _getCSNMultipleRefrenentialConditions(refConstraints, navPropName, role) {
1066
999
  let csn = "";
1067
1000
  csn = csn + '"on": [\n';
1068
1001
  Object.keys(refConstraints).forEach((i) => {
@@ -1146,8 +1079,7 @@ function _getCSNRefrenentialConstraints(associations, navPropName, toRole) {
1146
1079
  });
1147
1080
  if (refConstraints.length > 0) {
1148
1081
  // Multiple referential constraints within Association
1149
- csn =
1150
- csn +
1082
+ csn = csn +
1151
1083
  _getCSNMultipleRefrenentialConditions(
1152
1084
  refConstraints,
1153
1085
  navPropName,
@@ -1155,8 +1087,7 @@ function _getCSNRefrenentialConstraints(associations, navPropName, toRole) {
1155
1087
  );
1156
1088
  } else {
1157
1089
  // Single referential constraint within Association
1158
- csn =
1159
- csn +
1090
+ csn = csn +
1160
1091
  _getCSNRefrenentialConditions(
1161
1092
  refConstraints,
1162
1093
  navPropName,
@@ -1171,7 +1102,8 @@ function _getCSNAssociatedRefrenentialConstraints(
1171
1102
  toRole,
1172
1103
  entityName,
1173
1104
  navPropName,
1174
- mockServerUc
1105
+ mockServerUc,
1106
+ parserContext
1175
1107
  ) {
1176
1108
  let csn = "";
1177
1109
  let multiplicity;
@@ -1184,7 +1116,8 @@ function _getCSNAssociatedRefrenentialConstraints(
1184
1116
  associations.End,
1185
1117
  toRole,
1186
1118
  entityName,
1187
- mockServerUc
1119
+ mockServerUc,
1120
+ parserContext
1188
1121
  );
1189
1122
  if (multiplicity) {
1190
1123
  csn = csn + ",\n" + multiplicity;
@@ -1205,20 +1138,23 @@ function _getCSNAssociatedEntitySet(
1205
1138
  relationshipName,
1206
1139
  toRole,
1207
1140
  navPropName,
1208
- mockServerUc
1141
+ mockServerUc,
1142
+ parserContext
1209
1143
  ) {
1210
- let associationSet = allAssociationSets[relationshipName];
1211
- if(associationSet === undefined) {
1144
+ let associationSet = parserContext.allAssociationSets[relationshipName];
1145
+ if (associationSet === undefined) {
1146
+ console.log(relationshipName + " " + parserContext.serviceNamespace);
1212
1147
  throw new Error(messages.MISSING_ASSOCIATION_SETS);
1213
1148
  }
1214
1149
  let associationName = associationSet.Name;
1215
1150
  let entityName = _getAssociatedEntity(
1216
1151
  associationSet.End,
1217
1152
  toRole,
1218
- mockServerUc
1153
+ mockServerUc,
1154
+ parserContext
1219
1155
  );
1220
1156
  let differentAssociationNames;
1221
- if (!allAssociations[associationName]) {
1157
+ if (!parserContext.allAssociations[associationName]) {
1222
1158
  let array = relationshipName.split(".");
1223
1159
  if (
1224
1160
  array != "undefined" &&
@@ -1226,40 +1162,62 @@ function _getCSNAssociatedEntitySet(
1226
1162
  array.length != null &&
1227
1163
  array.length > 0
1228
1164
  ) {
1229
- differentAssociationNames =
1230
- allAssociations[array[array.length - 1]];
1165
+ differentAssociationNames = parserContext.allAssociations[array[array.length - 1]];
1231
1166
  }
1232
1167
  } else {
1233
- differentAssociationNames = allAssociations[associationName];
1168
+ differentAssociationNames = parserContext.allAssociations[associationName];
1234
1169
  }
1235
1170
  return _getCSNAssociatedRefrenentialConstraints(
1236
1171
  differentAssociationNames,
1237
1172
  toRole,
1238
1173
  entityName,
1239
1174
  navPropName,
1240
- mockServerUc
1175
+ mockServerUc,
1176
+ parserContext
1241
1177
  );
1242
1178
  }
1243
1179
 
1244
- function _getServiceEntityNavigationProperty(navPropAttributes, mockServerUc) {
1180
+ function _findAssociationType(relationshipName, fromRole, parserContext) {
1181
+ const associationName = relationshipName.replace(parserContext.serviceNamespace + '.', '');
1182
+ const associationEnds = parserContext.allAssociations[associationName].End;
1183
+ let associationType;
1184
+
1185
+ for (let i = 0; i < associationEnds.length; i++) {
1186
+ let potentialComposition = false;
1187
+ Object.keys(associationEnds[i]).forEach((key) => {
1188
+ if (key === "_attributes" && associationEnds[i][key].Role === fromRole)
1189
+ potentialComposition = true;
1190
+ if (key === "OnDelete"
1191
+ && associationEnds[i][key]._attributes.Action === "Cascade"
1192
+ && potentialComposition
1193
+ ) {
1194
+ associationType = "composition";
1195
+ }
1196
+ });
1197
+ }
1198
+
1199
+ return '"type": "cds.' + (associationType === "composition" ? 'Composition"' : 'Association"') + ',\n';
1200
+ }
1201
+
1202
+ function _getServiceEntityNavigationProperty(navPropAttributes, mockServerUc, parserContext) {
1245
1203
  let csn = "";
1246
1204
  let navPropName;
1247
1205
  let relationshipName;
1248
1206
  let navPropDoc;
1249
- let allowedNamespaceAttributes = namespaceAttributeFilter(navPropAttributes);
1250
- // var fromRole;
1207
+ let allowedNamespaceAttributes = namespaceAttributeFilter(navPropAttributes, parserContext);
1208
+ let fromRole;
1251
1209
  let toRole;
1252
1210
  if (!navPropAttributes) {
1253
1211
  return csn;
1254
1212
  }
1255
1213
  navPropName = navPropAttributes.Name;
1256
1214
  relationshipName = navPropAttributes.Relationship;
1257
- // fromRole = navPropAttributes.FromRole;
1215
+ fromRole = navPropAttributes.FromRole;
1258
1216
  toRole = navPropAttributes.ToRole;
1259
1217
  navPropDoc = navPropAttributes.doc;
1260
1218
 
1261
1219
  csn = csn + '"' + navPropName + '": {\n';
1262
- if(allowedNamespaceAttributes.length) {
1220
+ if (allowedNamespaceAttributes.length) {
1263
1221
  csn += _generateNamespaceAttributes(allowedNamespaceAttributes, false);
1264
1222
  }
1265
1223
  // annotation for on conditions
@@ -1267,16 +1225,17 @@ function _getServiceEntityNavigationProperty(navPropAttributes, mockServerUc) {
1267
1225
  // if documentation exists for navigation property
1268
1226
  if (navPropDoc)
1269
1227
  csn = csn + '"doc":' + ` "${navPropDoc}",\n`;
1270
- csn = csn + '"type": "cds.Association",\n';
1228
+ csn = csn + _findAssociationType(relationshipName, fromRole, parserContext);
1271
1229
  csn = csn +
1272
1230
  _getCSNAssociatedEntitySet(
1273
1231
  relationshipName,
1274
1232
  toRole,
1275
1233
  navPropName,
1276
- mockServerUc
1234
+ mockServerUc,
1235
+ parserContext
1277
1236
  );
1278
1237
  // Convert managed associations and compositions in unmanaged with empty key to avoid
1279
- // "generation" of keys, that do not exist in the external service.
1238
+ // "generation" of keys, that do not exist in the external service.
1280
1239
  if (common.checkForEmptyKeys(csn, "V2")) {
1281
1240
  csn = csn + ',\n"keys": []\n';
1282
1241
  }
@@ -1288,10 +1247,10 @@ function _getServiceEntityNavigationProperty(navPropAttributes, mockServerUc) {
1288
1247
  function _generateCSNEntityNavigationProperties(
1289
1248
  entityNavigationPropertiesMap,
1290
1249
  hasProperties,
1291
- mockServerUc
1250
+ mockServerUc,
1251
+ parserContext
1292
1252
  ) {
1293
1253
  let csn = "";
1294
- let i;
1295
1254
  let entityNavProperties;
1296
1255
  let navProperty;
1297
1256
  let navPropAttributes;
@@ -1304,14 +1263,14 @@ function _generateCSNEntityNavigationProperties(
1304
1263
  // Has navigation properties
1305
1264
  csn = ",\n";
1306
1265
  }
1307
- for (i = 0; i < entityNavProperties.length; i++) {
1266
+ for (let i = 0; i < entityNavProperties.length; i++) {
1308
1267
  navProperty = entityNavProperties[i];
1309
1268
  navPropAttributes = entityNavigationPropertiesMap[navProperty];
1310
- csn =
1311
- csn +
1269
+ csn = csn +
1312
1270
  _getServiceEntityNavigationProperty(
1313
1271
  navPropAttributes,
1314
- mockServerUc
1272
+ mockServerUc,
1273
+ parserContext
1315
1274
  );
1316
1275
  if (i < entityNavProperties.length - 1) {
1317
1276
  csn = csn + ",\n";
@@ -1320,18 +1279,17 @@ function _generateCSNEntityNavigationProperties(
1320
1279
  return csn;
1321
1280
  }
1322
1281
 
1323
- function _getBaseTypeEntityName(entityName, serviceNamespaceParam) {
1282
+ function _getBaseTypeEntityName(entityName, parserContext) {
1324
1283
  let baseTypeName;
1325
1284
  // if one entity type has mapping to multiple entity sets, use the first entity set
1326
- if (allEntitySetMapMC[entityName]) {
1327
- baseTypeName = serviceNamespaceParam + "." + allEntitySetMapMC[entityName][0];
1285
+ if (parserContext.allEntitySetMapMC[entityName]) {
1286
+ baseTypeName = parserContext.serviceNamespace + "." + parserContext.allEntitySetMapMC[entityName][0];
1328
1287
  return baseTypeName;
1329
1288
  }
1330
1289
  return entityName;
1331
1290
  }
1332
1291
 
1333
1292
  function _constructServiceEntity(
1334
- serviceNamespaceParam,
1335
1293
  entityName,
1336
1294
  entityKeysList,
1337
1295
  entityPropertiesMap,
@@ -1339,18 +1297,19 @@ function _constructServiceEntity(
1339
1297
  entityAttributes,
1340
1298
  ignorePersistenceSkip,
1341
1299
  mockServerUc,
1342
- documentation
1300
+ documentation,
1301
+ parserContext
1343
1302
  ) {
1344
1303
  let filteredNamespaces = {};
1345
1304
  let namespaces = [];
1346
- let serviceEntityName = serviceNamespaceParam + "." + entityName;
1305
+ let serviceEntityName = parserContext.serviceNamespace + "." + entityName;
1347
1306
  let csnEntity = '"' + serviceEntityName + '": {\n';
1348
1307
  let csnKeys;
1349
1308
  let csnProperties;
1350
1309
  let hasProperties;
1351
1310
  csnEntity = csnEntity + '"kind": "entity",\n';
1352
- if (ignorePersistenceSkip === false) {
1353
- csnEntity = csnEntity + '"@cds.persistence.skip": true,\n';
1311
+ if (ignorePersistenceSkip === false) {
1312
+ csnEntity = csnEntity + '"@cds.persistence.skip": true,\n';
1354
1313
  }
1355
1314
  if (entityAttributes.Abstract && entityAttributes.Abstract.toUpperCase() === "TRUE") {
1356
1315
  csnEntity = csnEntity + '"abstract": true,\n';
@@ -1358,14 +1317,14 @@ function _constructServiceEntity(
1358
1317
 
1359
1318
  /* Merging the namespace list from entity set and entity type
1360
1319
  And in case of same label, entity set's value will have precedence */
1361
- if(allEntitySetNamespaces[entityName]){
1362
- allEntitySetNamespaces[entityName].forEach((item) => {
1320
+ if (parserContext.allEntitySetNamespaces[entityName]) {
1321
+ parserContext.allEntitySetNamespaces[entityName].forEach((item) => {
1363
1322
  filteredNamespaces[Object.keys(item)[0]] = Object.values(item)[0];
1364
1323
  });
1365
1324
  }
1366
- if(entityAttributes.allowedNamespaceAttributes.length){
1325
+ if (entityAttributes.allowedNamespaceAttributes.length) {
1367
1326
  entityAttributes.allowedNamespaceAttributes.forEach((item) => {
1368
- if(!filteredNamespaces[Object.keys(item)[0]]){
1327
+ if (!filteredNamespaces[Object.keys(item)[0]]) {
1369
1328
  filteredNamespaces[Object.keys(item)[0]] = Object.values(item)[0];
1370
1329
  }
1371
1330
  });
@@ -1373,12 +1332,12 @@ function _constructServiceEntity(
1373
1332
  Object.keys(filteredNamespaces).forEach((item) => {
1374
1333
  let obj = {};
1375
1334
  obj[item] = filteredNamespaces[item];
1376
- namespaces.push(obj)
1335
+ namespaces.push(obj);
1377
1336
  });
1378
1337
 
1379
- if(namespaces)
1338
+ if (namespaces)
1380
1339
  csnEntity += _generateNamespaceAttributes(namespaces, false);
1381
-
1340
+
1382
1341
  // if documentation exists for the entity
1383
1342
  if (documentation) {
1384
1343
  csnEntity = csnEntity + `"doc": "${documentation}",` + '\n';
@@ -1386,19 +1345,16 @@ function _constructServiceEntity(
1386
1345
  csnEntity = csnEntity + '"elements": {\n';
1387
1346
 
1388
1347
  // Key Entity attributes
1389
- csnKeys = _generateCSNEntityKeys(entityKeysList, entityPropertiesMap);
1348
+ csnKeys = _generateCSNEntityKeys(entityKeysList, entityPropertiesMap, parserContext);
1390
1349
 
1391
1350
  // Non key Entity attributes
1392
- csnProperties = _generateCSNEntityProperties(
1393
- entityKeysList,
1394
- entityPropertiesMap
1395
- );
1351
+ csnProperties = _generateCSNEntityProperties(entityKeysList, entityPropertiesMap, parserContext);
1396
1352
  csnProperties = csnKeys + csnProperties;
1397
1353
  //to remove additional ',\n' in case key datatype is undefined
1398
1354
  if (csnProperties && csnProperties.startsWith(",\n")) {
1399
1355
  csnProperties = csnProperties.substring(csnProperties.indexOf(",\n") + 2);
1400
1356
  }
1401
-
1357
+
1402
1358
  csnEntity = csnEntity + csnProperties;
1403
1359
 
1404
1360
  // No keys and No properties found
@@ -1407,45 +1363,50 @@ function _constructServiceEntity(
1407
1363
  hasProperties = false;
1408
1364
  }
1409
1365
  // Entity navigation properties
1410
- csnEntity =
1411
- csnEntity +
1366
+ csnEntity = csnEntity +
1412
1367
  _generateCSNEntityNavigationProperties(
1413
1368
  entityNavigationPropertiesMap,
1414
1369
  hasProperties,
1415
- mockServerUc
1370
+ mockServerUc,
1371
+ parserContext
1416
1372
  );
1417
1373
  csnEntity = csnEntity + "}\n";
1418
1374
 
1419
1375
  if (entityAttributes.BaseType) {
1420
- let baseTypeName = _getBaseTypeEntityName(entityAttributes.BaseType, serviceNamespaceParam);
1376
+ let baseTypeName = _getBaseTypeEntityName(entityAttributes.BaseType, parserContext);
1421
1377
  csnEntity = csnEntity + ",\n";
1422
1378
  csnEntity = csnEntity + '"includes": ["' + baseTypeName + '"]\n';
1423
1379
  }
1424
1380
 
1425
1381
  //if the function import is bounded to entitySet
1426
- if (allFunctionImportsMap[entityName])
1427
- {
1382
+ if (parserContext.allFunctionImportsMap[entityName]) {
1428
1383
  csnEntity = csnEntity + ', \n "actions": {\n';
1429
- csnEntity = csnEntity + _getAllFunctionImports(allFunctionImportsMap[entityName],1,entityKeysList);
1384
+ csnEntity = csnEntity +
1385
+ _getAllFunctionImports(parserContext.allFunctionImportsMap[entityName],
1386
+ 1, entityKeysList, parserContext
1387
+ );
1430
1388
  csnEntity = csnEntity + "}";
1431
1389
  }
1432
- else if (allFunctionImportsMap[_extractEntityFromNamespace(allEntitySetMap[entityName])]) //if the function import is bounded to entityType
1433
- {
1390
+ // if the function import is bounded to entityType
1391
+ else if (parserContext.allFunctionImportsMap[_extractEntityFromNamespace(parserContext.allEntitySetMap[entityName])]) {
1434
1392
  csnEntity = csnEntity + ', \n "actions": {\n';
1435
- csnEntity = csnEntity + _getAllFunctionImports(allFunctionImportsMap[_extractEntityFromNamespace(allEntitySetMap[entityName])],1,entityKeysList);
1393
+ csnEntity = csnEntity +
1394
+ _getAllFunctionImports(
1395
+ parserContext.allFunctionImportsMap[_extractEntityFromNamespace(parserContext.allEntitySetMap[entityName])],
1396
+ 1, entityKeysList, parserContext
1397
+ );
1436
1398
  csnEntity = csnEntity + "}";
1437
1399
  }
1438
1400
 
1439
1401
  return csnEntity;
1440
1402
  }
1441
1403
 
1442
- function _parseServiceEntity(
1443
- serviceNamespaceParam,
1444
- entityName,
1445
- entity,
1446
- ignorePersistenceSkip,
1447
- mockServerUc
1448
- ) {
1404
+ function _addBlobElement(properties) {
1405
+ const blobElement = ['Edm.Stream', -1, -1, -1, -1, -1, -1];
1406
+ properties['blob'] = blobElement;
1407
+ }
1408
+
1409
+ function _parseServiceEntity(entityName, entity, ignorePersistenceSkip, mockServerUc, parserContext) {
1449
1410
  let entityAttributes;
1450
1411
  let entityKeysList;
1451
1412
  let entityPropertiesMap;
@@ -1453,11 +1414,11 @@ function _parseServiceEntity(
1453
1414
  let documentation;
1454
1415
  Object.keys(entity).forEach((key) => {
1455
1416
  if (key === "_attributes") {
1456
- entityAttributes = _parseEntityAttributes(entity[key]);
1417
+ entityAttributes = _parseEntityAttributes(entity[key], parserContext);
1457
1418
  } else if (key.toUpperCase() === "Key".toUpperCase()) {
1458
1419
  entityKeysList = _parseEntityKeys(entity[key]);
1459
1420
  } else if (key.toUpperCase() === "Property".toUpperCase()) {
1460
- entityPropertiesMap = _parseEntityProperty(entity[key]);
1421
+ entityPropertiesMap = _parseEntityProperty(entity[key], parserContext);
1461
1422
  } else if (key.toUpperCase() === "NavigationProperty".toUpperCase()) {
1462
1423
  entityNavigationPropertiesMap = _parseNavigationProperty(entity[key]);
1463
1424
  } else if (key.toUpperCase() === "Documentation".toUpperCase()) {
@@ -1478,12 +1439,13 @@ function _parseServiceEntity(
1478
1439
  }
1479
1440
  // If inherited entity found
1480
1441
  if (entityAttributes.BaseType) {
1481
- allEntities.push(
1482
- _extractEntityFromNamespace(entityAttributes.BaseType)
1483
- );
1442
+ parserContext.allEntities.push(_extractEntityFromNamespace(entityAttributes.BaseType));
1484
1443
  }
1444
+ // adding blob element if entity has m:HasStream as true
1445
+ const checkProperty = entityAttributes["allowedNamespaceAttributes"].filter(e => e["m.HasStream"] === 'true');
1446
+ if (checkProperty.length === 1) _addBlobElement(entityPropertiesMap);
1447
+
1485
1448
  return _constructServiceEntity(
1486
- serviceNamespaceParam,
1487
1449
  entityName,
1488
1450
  entityKeysList,
1489
1451
  entityPropertiesMap,
@@ -1491,18 +1453,19 @@ function _parseServiceEntity(
1491
1453
  entityAttributes,
1492
1454
  ignorePersistenceSkip,
1493
1455
  mockServerUc,
1494
- documentation
1456
+ documentation,
1457
+ parserContext
1495
1458
  );
1496
1459
  }
1497
1460
 
1498
- function _getEntitesWithNamesFromEntitySets(serviceNamespaceParam, entityJson, mockServerUc) {
1461
+ function _getEntitesWithNamesFromEntitySets(entityJson, mockServerUc, parserContext) {
1499
1462
  const getEntityName = mockServerUc
1500
- ? (entity) => allEntitySetMapMC[serviceNamespaceParam + "." + _getEntityName(entity)]
1463
+ ? (entity) => parserContext.allEntitySetMapMC[parserContext.serviceNamespace + "." + _getEntityName(entity)]
1501
1464
  : (entity) => [_getEntityName(entity)];
1502
1465
 
1503
1466
  const isNameInEntitySet = mockServerUc
1504
- ? (name) => allEntitiesMC.indexOf(name) >= 0
1505
- : (name) => allEntities.indexOf(name) >= 0;
1467
+ ? (name) => parserContext.allEntitiesMC.indexOf(name) >= 0
1468
+ : (name) => parserContext.allEntities.indexOf(name) >= 0;
1506
1469
 
1507
1470
  const getEntitySetNames = entityWithName => {
1508
1471
  if (!entityWithName.name) return false;
@@ -1521,60 +1484,50 @@ function _getEntitesWithNamesFromEntitySets(serviceNamespaceParam, entityJson, m
1521
1484
  .filter((entityWithName) => getEntitySetNames(entityWithName));
1522
1485
  }
1523
1486
 
1524
- function _getEntitesWithNamesFromEntityTypes(serviceNamespaceParam, entityJson) {
1487
+ function _getEntitesWithNamesFromEntityTypes(entityJson, parserContext) {
1525
1488
  let entities = [];
1526
1489
  // we are not making any decision here on the basis of mockserverUc variable as of now
1527
1490
  for (let i = 0; i < entityJson.length; i++) {
1528
1491
  let entity = _getEntityName(entityJson[i]);
1529
1492
  // if entity doesn't have any mapping with entity set,
1530
1493
  // then collect those entityType
1531
- if (!allEntitySetMapMC[serviceNamespaceParam + "." + entity]) {
1532
- entities.push( {
1533
- entity: entityJson[i],
1534
- name: [entity]
1535
- } );
1494
+ if (!parserContext.allEntitySetMapMC[parserContext.serviceNamespace + "." + entity]) {
1495
+ entities.push({
1496
+ entity: entityJson[i],
1497
+ name: [entity]
1498
+ });
1536
1499
  }
1537
1500
  }
1538
1501
 
1539
1502
  return entities;
1540
1503
  }
1541
1504
 
1542
- function _parsingServiceEntities(
1543
- entitiesWithNames,
1544
- serviceNamespaceParam,
1545
- ignorePersistenceSkip,
1546
- mockServerUc
1547
- ){
1548
- return entitiesWithNames.map((entityWithName) =>
1549
- entityWithName.name.map((entityName) =>
1550
- _parseServiceEntity(
1551
- serviceNamespaceParam,
1552
- entityName,
1553
- entityWithName.entity,
1554
- ignorePersistenceSkip,
1555
- mockServerUc
1556
- )
1557
- ).join("},") + "}"
1558
- );
1505
+ function _parsingServiceEntities(entitiesWithNames, ignorePersistenceSkip, mockServerUc, parserContext) {
1506
+ return entitiesWithNames.map((entityWithName) =>
1507
+ entityWithName.name.map((entityName) =>
1508
+ _parseServiceEntity(
1509
+ entityName,
1510
+ entityWithName.entity,
1511
+ ignorePersistenceSkip,
1512
+ mockServerUc,
1513
+ parserContext
1514
+ )
1515
+ ).join("},") + "}"
1516
+ );
1559
1517
  }
1560
1518
 
1561
- function _getServiceEntitites(
1562
- serviceNamespaceParam,
1563
- entityJson = [],
1564
- ignorePersistenceSkip,
1565
- mockServerUc
1566
- ) {
1519
+ function _getServiceEntitites(entityJson = [], ignorePersistenceSkip, mockServerUc, parserContext) {
1567
1520
  const entities = Array.isArray(entityJson) ? entityJson : [entityJson];
1568
1521
  let entitiesWithNames = []; // [0]-> entity set, [1]-> entity type
1569
1522
  let parsedEntities = []; // [0]-> entity set, [1]-> entity type
1570
1523
 
1571
- entitiesWithNames[0] = _getEntitesWithNamesFromEntitySets(serviceNamespaceParam, entities, mockServerUc);
1572
- entitiesWithNames[1] = _getEntitesWithNamesFromEntityTypes(serviceNamespaceParam, entities);
1524
+ entitiesWithNames[0] = _getEntitesWithNamesFromEntitySets(entities, mockServerUc, parserContext);
1525
+ entitiesWithNames[1] = _getEntitesWithNamesFromEntityTypes(entities, parserContext);
1573
1526
 
1574
1527
  for (let i = 0; i < 2; i++) {
1575
1528
  if (entitiesWithNames[i].length) {
1576
1529
  parsedEntities[i] = _parsingServiceEntities(entitiesWithNames[i],
1577
- serviceNamespaceParam, ignorePersistenceSkip, mockServerUc);
1530
+ ignorePersistenceSkip, mockServerUc, parserContext);
1578
1531
  }
1579
1532
  }
1580
1533
  // if entities from entity set and entity type both are parsed
@@ -1588,91 +1541,76 @@ function _getServiceEntitites(
1588
1541
  return "";
1589
1542
  }
1590
1543
 
1591
- function _generateEDMXJSON2CSN(
1592
- jsonObj,
1593
- serviceNamespaceParam,
1594
- ignorePersistenceSkip,
1595
- mockServerUc
1596
- ) {
1544
+ function _generateEDMXJSON2CSN(jsonObj, ignorePersistenceSkip, mockServerUc, parserContext) {
1597
1545
  const csn = {};
1598
1546
  csn.meta = {};
1599
- csn.meta.creator = 'cds-dk ' + versionInfo;
1547
+ csn.meta.creator = 'cds-dk ' + versionInfo;
1600
1548
  csn.$version = '2.0';
1601
1549
  csn.definitions = {};
1602
1550
 
1603
1551
  // Extract association sets
1604
- let associationSets =
1605
- jsonObj["edmx:Edmx"]["edmx:DataServices"].Schema.EntityContainer
1606
- .AssociationSet;
1552
+ let associationSets = jsonObj["edmx:Edmx"]["edmx:DataServices"].Schema.EntityContainer.AssociationSet;
1607
1553
  if (associationSets) {
1608
- _extractAllAssociationSets(associationSets);
1554
+ _extractAllAssociationSets(associationSets, parserContext);
1609
1555
  }
1610
1556
  // Extract associations
1611
- const associations =
1612
- jsonObj["edmx:Edmx"]["edmx:DataServices"].Schema.Association;
1557
+ const associations = jsonObj["edmx:Edmx"]["edmx:DataServices"].Schema.Association;
1613
1558
  if (associations) {
1614
- _extractAllAssociations(associations);
1559
+ _extractAllAssociations(associations, parserContext);
1615
1560
  }
1616
1561
  // Extract entities from EntitySets
1617
- const entitySets =
1618
- jsonObj["edmx:Edmx"]["edmx:DataServices"].Schema.EntityContainer
1619
- .EntitySet;
1562
+ const entitySets = jsonObj["edmx:Edmx"]["edmx:DataServices"].Schema.EntityContainer.EntitySet;
1620
1563
  if (entitySets) {
1621
- _extractAllEntityFromEntitySets(entitySets);
1564
+ _extractAllEntityFromEntitySets(entitySets, parserContext);
1622
1565
  }
1623
1566
  // Extract function imports
1624
- const functionImports =
1625
- jsonObj["edmx:Edmx"]["edmx:DataServices"].Schema.EntityContainer
1626
- .FunctionImport;
1627
- if(functionImports) {
1628
- _extractAllFunctionImports(functionImports, serviceNamespaceParam);
1567
+ const functionImports = jsonObj["edmx:Edmx"]["edmx:DataServices"].Schema.EntityContainer.FunctionImport;
1568
+ if (functionImports) {
1569
+ _extractAllFunctionImports(functionImports, parserContext);
1629
1570
  }
1630
1571
  // Extract complex types
1631
- const complexTypes =
1632
- jsonObj["edmx:Edmx"]["edmx:DataServices"].Schema.ComplexType;
1572
+ const complexTypes = jsonObj["edmx:Edmx"]["edmx:DataServices"].Schema.ComplexType;
1633
1573
  if (complexTypes) {
1634
- _extractAllComplexTypes(complexTypes, serviceNamespaceParam);
1574
+ _extractAllComplexTypes(complexTypes, parserContext);
1635
1575
  }
1636
1576
 
1637
1577
  // Construct CSN entity based on EDMX entity
1638
- const entityJson =
1639
- jsonObj["edmx:Edmx"]["edmx:DataServices"].Schema.EntityType;
1578
+ const entityJson = jsonObj["edmx:Edmx"]["edmx:DataServices"].Schema.EntityType;
1640
1579
  const definitions = [];
1641
1580
 
1642
1581
  if (mockServerUc) {
1643
- let def = '"' + serviceNamespaceParam + '": {"kind": "service"' + ',\n' + '"@cds.external": true';
1582
+ let def = '"' + parserContext.serviceNamespace + '": {"kind": "service"' + ',\n' + '"@cds.external": true';
1644
1583
  let serviceDoc = jsonObj["edmx:Edmx"]["edmx:DataServices"]["Schema"].EntityContainer.Documentation;
1645
- let namespaceAttributes = namespaceAttributeFilter(jsonObj["edmx:Edmx"]["edmx:DataServices"]["Schema"].EntityContainer["_attributes"]);
1584
+ let namespaceAttributes = namespaceAttributeFilter(
1585
+ jsonObj["edmx:Edmx"]["edmx:DataServices"]["Schema"].EntityContainer["_attributes"], parserContext
1586
+ );
1646
1587
  // if documentation exists for service
1647
1588
  if (serviceDoc) {
1648
1589
  let doc = _parseDocumentationTag(serviceDoc);
1649
1590
  if (doc) def += ',\n' + `"doc": "${doc}"`;
1650
1591
  }
1651
- if(namespaceAttributes.length)
1652
- def += _generateNamespaceAttributes(namespaceAttributes,true);
1592
+ if (namespaceAttributes.length)
1593
+ def += _generateNamespaceAttributes(namespaceAttributes, true);
1653
1594
  def += "}";
1654
1595
  definitions.push(def);
1655
1596
  }
1656
1597
 
1657
1598
  // If complex type exists
1658
1599
  if (complexTypes) {
1659
- definitions.push(_getServiceComplexTypes());
1600
+ definitions.push(_getServiceComplexTypes(parserContext));
1660
1601
  }
1661
1602
 
1662
- //if there are unbounded function imports
1663
- if(Object.keys(allFunctionImports).length > 0)
1664
- {
1665
- definitions.push(_getAllFunctionImports(allFunctionImports,0,0)); //passing 0 for unbounded actions/functions and 0 for entityKeysList
1603
+ // if there are unbounded function imports
1604
+ if (Object.keys(parserContext.allFunctionImports).length > 0) {
1605
+ // passing 0 for unbounded actions/functions and 0 for entityKeysList
1606
+ definitions.push(
1607
+ _getAllFunctionImports(parserContext.allFunctionImports, 0, 0, parserContext)
1608
+ );
1666
1609
  }
1667
1610
 
1668
1611
  if (entityJson) {
1669
1612
  definitions.push(
1670
- _getServiceEntitites(
1671
- serviceNamespaceParam,
1672
- entityJson,
1673
- ignorePersistenceSkip,
1674
- mockServerUc
1675
- )
1613
+ _getServiceEntitites(entityJson, ignorePersistenceSkip, mockServerUc, parserContext)
1676
1614
  );
1677
1615
  }
1678
1616
 
@@ -1684,35 +1622,34 @@ function _generateEDMXJSON2CSN(
1684
1622
  }
1685
1623
  }
1686
1624
 
1687
- function getEdmxv2CSN(
1688
- edmx2jsonModel,
1689
- ignorePersistenceSkip,
1690
- mockServerUc,
1691
- context
1692
- ) {
1625
+ function getEdmxv2CSN(edmx2jsonModel, ignorePersistenceSkip, mockServerUc, context) {
1693
1626
  let csnDataModel;
1694
1627
  let isValid;
1695
- _initialize();
1628
+
1629
+ const parserContext = {};
1630
+ _initialize(parserContext);
1631
+
1696
1632
  if (!context.include_all_namespaces && context.namespaces.length) {
1697
- allowedNamespaces = allowedNamespaces.concat(context.namespaces)
1633
+ parserContext.allowedNamespaces = parserContext.allowedNamespaces.concat(context.namespaces)
1634
+ }
1635
+ else if (context.include_all_namespaces) {
1636
+ parserContext.allowAllNamespaces = true;
1698
1637
  }
1699
- else if(context.include_all_namespaces) {
1700
- allowAllNamespaces = true;
1701
- }
1702
1638
 
1703
1639
  isValid = _validateEDMX(edmx2jsonModel);
1704
1640
  if (isValid) {
1705
- serviceNamespace = _getServiceNameSpace(edmx2jsonModel);
1641
+ parserContext.serviceNamespace = _getServiceNameSpace(edmx2jsonModel);
1706
1642
  let namespaceAlias = edmx2jsonModel["edmx:Edmx"]["edmx:DataServices"].Schema._attributes.Alias;
1707
1643
  // replace the namespace alias value with original namespace value
1708
1644
  if (namespaceAlias) {
1709
- edmx2jsonModel = common.replaceAliasValue(JSON.stringify(edmx2jsonModel), serviceNamespace, namespaceAlias);
1645
+ edmx2jsonModel = common.replaceAliasValue(JSON.stringify(edmx2jsonModel),
1646
+ parserContext.serviceNamespace, namespaceAlias);
1710
1647
  }
1711
1648
  csnDataModel = _generateEDMXJSON2CSN(
1712
1649
  edmx2jsonModel,
1713
- serviceNamespace,
1714
1650
  ignorePersistenceSkip,
1715
- mockServerUc
1651
+ mockServerUc,
1652
+ parserContext
1716
1653
  );
1717
1654
  }
1718
1655
  return csnDataModel;