@sap/cds-dk 4.5.2 → 4.6.2

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 (42) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/bin/bind.js +124 -8
  3. package/bin/cds-ts.js +1 -1
  4. package/bin/cds.js +1 -0
  5. package/bin/compile/index.js +2 -1
  6. package/bin/env.js +50 -9
  7. package/bin/help.js +1 -0
  8. package/bin/import.js +38 -18
  9. package/bin/repl.js +6 -2
  10. package/bin/watch.js +58 -13
  11. package/lib/bind/bindingResolver.js +138 -0
  12. package/lib/bind/cfKeyProvider.js +353 -0
  13. package/lib/bind/userCdsrcJsonStorageProvider.js +144 -0
  14. package/lib/client/auth_manager.js +4 -4
  15. package/lib/client/settings_manager.js +6 -5
  16. package/lib/import/common.js +10 -1
  17. package/lib/import/importapi.js +4 -3
  18. package/lib/import/index.js +34 -5
  19. package/lib/import/message.js +2 -1
  20. package/lib/import/utils/MetadataConverter.js +25 -4
  21. package/lib/import/utils/MetadataConverterFactory.js +1 -2
  22. package/lib/import/utils/MultiMap.js +26 -0
  23. package/lib/import/v2parser.js +131 -12
  24. package/lib/import/v4parser.js +214 -168
  25. package/lib/init/constants.js +1 -1
  26. package/lib/init/index.js +2 -0
  27. package/lib/init/template/lint/files/.eslint/rules/no-entity-moo.js +36 -52
  28. package/lib/init/template/lint/files/.eslint/tests/no-entity-moo/rule.test.js +15 -0
  29. package/lib/init/template/lint/index.js +19 -17
  30. package/lib/init/template/mta/files/mta.yaml.hbs +0 -7
  31. package/lib/init/template/mtx/files/xs-security.json.hbs +3 -1
  32. package/lib/init/template/mtx/package/dependencies.package.json +1 -1
  33. package/lib/init/template/nodejs/files/.gitignore.hbs +1 -0
  34. package/lib/init/util/commandUtil.js +5 -0
  35. package/lib/lint/Linter.js +17 -20
  36. package/lib/lint/generators.js +5 -4
  37. package/lib/lint/io.js +62 -36
  38. package/lib/util/term.js +2 -0
  39. package/lib/watch/node-watch.js +38 -19
  40. package/npm-shrinkwrap.json +1485 -1959
  41. package/package.json +3 -3
  42. package/lib/init/template/lint/files/.eslint/tests/no-entity-moo/test.js +0 -10
@@ -30,6 +30,14 @@ function checkForEmptyKeys(element, oDataVersion) {
30
30
  }
31
31
  }
32
32
 
33
+ //to replace the alias value with original schema namespace value
34
+ function replaceAliasValue(schemaContent, schemaNamespaceValue, aliasValue){
35
+ const re = RegExp(`([("/])${aliasValue}([/").])`, 'g');
36
+ const val = `$1${schemaNamespaceValue}$2`;
37
+ schemaContent = schemaContent.replace(re, val);
38
+ return JSON.parse(schemaContent);
39
+ }
40
+
33
41
  async function _getODataVersion(edmx) {
34
42
  let oDataVersion;
35
43
  let jsonObj;
@@ -115,5 +123,6 @@ module.exports = {
115
123
  getVersion,
116
124
  getSuffix,
117
125
  supportedFormats,
118
- checkForEmptyKeys
126
+ checkForEmptyKeys,
127
+ replaceAliasValue
119
128
  };
@@ -1,5 +1,7 @@
1
1
  const edm2csn = require('.');
2
-
2
+ let context={};
3
+ context.oDataInfo = {};
4
+ context.namespaces = [];
3
5
  /**
4
6
  * This is the import API function to generate CSN from XML/EDMX files.
5
7
  * @param {string} filepath
@@ -10,11 +12,10 @@ const edm2csn = require('.');
10
12
  * - other import options not supported
11
13
  * @returns {object} CSN
12
14
  */
13
- const oDataInfo={};
14
15
  module.exports = async function cds_import(filepath, options = {keepNamespace : false}) //namespace will be taken as false in case it is not mentioned
15
16
  {
16
17
  filepath = await edm2csn.isValidInputFile(filepath);
17
18
  let edmx= await edm2csn.getMetadataFromFile(filepath);
18
- let csn = await edm2csn.edmx2csn(edmx, !options.keepNamespace && filepath, false, oDataInfo);
19
+ let csn = await edm2csn.edmx2csn(edmx, !options.keepNamespace && filepath, context);
19
20
  return csn;
20
21
  }
@@ -116,7 +116,15 @@ function _convertEDMXWithMultipleSchemas(edmx, multipleSchemas, namespace) {
116
116
  </Schema>
117
117
  </edmx:DataServices>
118
118
  */
119
- edmx = edmx.replace(multipleSchemas, '').replace(/<Schema Namespace="[^"]+"/, `<Schema Namespace="${namespace}"`);
119
+
120
+ // Remove the ending and beginning of the first and second schema tag
121
+ edmx = edmx.replace(multipleSchemas, '');
122
+ // Now capture the schema tag details
123
+ let schemaDetails = edmx.match(/(<Schema [^>]*>)/);
124
+ // Replace the Namespace value with the correct one
125
+ schemaDetails = schemaDetails[0].replace(/Namespace="[^"]+"/, `Namespace="${namespace}"`);
126
+ // Place the above computed schema details in the edmx content
127
+ edmx = edmx.replace(/(<Schema [^>]*>)/, `${schemaDetails}`);
120
128
 
121
129
  return edmx;
122
130
  }
@@ -132,7 +140,7 @@ async function edmx2csn(edmx, filename, context) {
132
140
  if (multipleSchemas.test(edmx)) {
133
141
  edmx = _convertEDMXWithMultipleSchemas(edmx, multipleSchemas, namespace);
134
142
  }
135
- let csn = await generateCSN(edmx, true, context);
143
+ let csn = await generateCSN(edmx, false, true, context);
136
144
  if (filename) {
137
145
  // Replace namespace by given filename in the csn file instead of edmx file
138
146
  const re = RegExp(`([("/])${namespace}([/").])`, 'g');
@@ -151,20 +159,33 @@ async function _generateEDMX2JSON(edmx) {
151
159
  return JSON.parse(cjson);
152
160
  }
153
161
 
154
- async function generateCSN(edmx, mockServerUc, context) {
162
+ async function generateCSN(edmx, ignorePersistenceSkip, mockServerUc, context) {
155
163
  let csn;
156
164
  let odataVersion;
157
165
  let edmx2jsonModel;
166
+ let defaultNamespaces;
167
+ let namespaces = [];
168
+ if(context.namespaces) namespaces.push(...(context.namespaces));
158
169
  odataVersion = await common.getVersion(edmx);
159
170
  if (odataVersion === "V2") {
160
171
  if(context){
161
172
  context.oDataVersion = "V2";
162
173
  }
174
+ //default namespaces to be present
175
+ if(!context.include_all_namespaces)
176
+ {
177
+ defaultNamespaces = ['edmx','sap','m'];
178
+ namespaces = namespaces.concat(defaultNamespaces);
179
+ namespaces = namespaces.filter((item,pos) => namespaces.indexOf(item) === pos); //removing duplicate values
180
+ }
181
+ context.namespaces = namespaces;
163
182
  edmx2jsonModel = await _generateEDMX2JSON(edmx);
164
183
  return new Promise(function getCsn(resolve, reject) {
165
184
  csn = edmxv2CSN.getEdmxv2CSN(
166
185
  edmx2jsonModel,
167
- mockServerUc
186
+ ignorePersistenceSkip,
187
+ mockServerUc,
188
+ context
168
189
  );
169
190
  if (csn) {
170
191
  resolve(csn);
@@ -177,7 +198,15 @@ async function generateCSN(edmx, mockServerUc, context) {
177
198
  if(context){
178
199
  context.oDataVersion = "V4";
179
200
  }
180
- return edmxv4CSN.getEdmxv4CSN(edmx, mockServerUc);
201
+ //default namespaces to be present
202
+ if(!context.include_all_namespaces)
203
+ {
204
+ defaultNamespaces = ['edmx'];
205
+ namespaces = namespaces.concat(defaultNamespaces);
206
+ namespaces = namespaces.filter((item,pos) => namespaces.indexOf(item) === pos); //removing duplicate values
207
+ }
208
+ context.namespaces = namespaces;
209
+ return edmxv4CSN.getEdmxv4CSN(edmx, ignorePersistenceSkip, mockServerUc, context);
181
210
  }
182
211
  return new Promise(function invalidFile(resolve, reject) {
183
212
  reject(new Error(messages.INVALID_EDMX_METADATA));
@@ -9,10 +9,11 @@ const messages = {
9
9
  MISSING_ENTITY_CONTAINER: 'There is no entity container in the OData model. Specify the correct OData model.',
10
10
  MISSING_ENTITY_SETS: 'There are no entity sets in the OData model. Specify the correct OData model.',
11
11
  INVALID_INPUT_FILE: 'Input file provided is not valid. Please provide a file with either .edmx or .xml extension.',
12
- FILE_MODIFIED: 'The file with the same name exists and is been modified. Use --f flag to forcefully overwrite the file.',
12
+ FILE_MODIFIED: 'The file with the same name exists and is been modified. Use --force flag to forcefully overwrite the file.',
13
13
  OUTPUT_FILE_MISMATCH: 'Specify the file extension that --as option supports.',
14
14
  INVALID_AS_OPTION: 'For --as option, please specify one of these output file format [cds, csn, json].',
15
15
  INCORRECT_EXTENSION: 'If --as option is not provided, then please provide either .json or .csn output file extension.',
16
+ INCORRECT_INPUT_NAMESPACES: 'Invalid value for --include-namespaces option. Specify namespaces as comma-separated list or "*"'
16
17
  };
17
18
 
18
19
  function getMessages() {
@@ -396,7 +396,7 @@ class Expression {
396
396
  const target = this.getTarget();
397
397
  const element = this.getElement();
398
398
  const attribs = element.attributes;
399
-
399
+ let custom_namespace = MetadataConverter.custom_namespace;
400
400
  if (attribs == null) return;
401
401
  let realType = attribs.Type || attribs.EntityType || attribs.UnderlyingType;
402
402
  const propertyName = attribs.UnderlyingType == null ? '$Type' : '$UnderlyingType';
@@ -574,9 +574,29 @@ class Expression {
574
574
  !(target.$Kind === 'NavigationProperty' && target.$Collection === true)) {
575
575
  target.$Nullable = true;
576
576
  }
577
+ const nonStdAttributes = this.getNonStdAttributes(element.attributes);
578
+ for (let i = 0; i < nonStdAttributes.length; i++) {
579
+ let attr = nonStdAttributes[i];
580
+ let [prefix, attrName] = attr.split(':');
581
+ if(attrName)
582
+ attrName = attrName.replace(/-/g,'.');
583
+ let attribute;
584
+ if ((custom_namespace.includes(prefix) && attrName !== undefined) || custom_namespace.includes(true))
585
+ attribute = "@" + prefix + "." + attrName;
586
+ else if (attrName === undefined)
587
+ attribute = "$" + prefix;
588
+ if (attribute !== undefined)
589
+ target[attribute] = element.attributes[attr];
590
+ }
591
+ }
592
+ getNonStdAttributes(attributes) {
593
+ const attributeList = [];
594
+ const standardArrtibutes = ['MaxLength', 'Precision', 'Scale', 'Nullable', 'DefaultValue',
595
+ 'Name', 'Type', 'HasStream', 'IsFlags', 'Alias', 'Namespace', 'BaseType', 'Partner',
596
+ 'IsComposable', 'ContainsTarget', 'IsBound', 'EntitySet', 'EntitySetPath', 'EntityType'];
597
+ attributeList.push(...Object.keys(attributes).filter(attribute => standardArrtibutes.indexOf(attribute) === -1));
598
+ return attributeList;
577
599
  }
578
-
579
-
580
600
  }
581
601
 
582
602
  class EdmPrimitiveType {
@@ -2361,7 +2381,8 @@ class OnDeleteExpression extends Expression {
2361
2381
  }
2362
2382
 
2363
2383
 
2364
- MetadataConverter.createOdataV4MetadataXmlToOdataV4CsdlStrategy = () => {
2384
+ MetadataConverter.createOdataV4MetadataXmlToOdataV4CsdlStrategy = (name_space) => {
2385
+ MetadataConverter.custom_namespace = name_space;
2365
2386
  return new MetadataConverter.DefaultXmlStrategy()
2366
2387
  .use('http://docs.oasis-open.org/odata/ns/edmx:Edmx', (element, parentExpression, context) => {
2367
2388
  return new EdmxRootExpression(element, null, context);
@@ -1,5 +1,4 @@
1
1
  'use strict';
2
-
3
2
  const xmljs = require('xml-js');
4
3
  const MetadataConverterV4 = require('../utils/MetadataConverter');
5
4
 
@@ -61,7 +60,7 @@ class MetadataConverterFactory {
61
60
  *
62
61
  */
63
62
  static createEdmxV40XmlToV40Json(options = {}) {
64
- const defaultStrategy = MetadataConverterV4.createOdataV4MetadataXmlToOdataV4CsdlStrategy();
63
+ const defaultStrategy = MetadataConverterV4.createOdataV4MetadataXmlToOdataV4CsdlStrategy(options);
65
64
 
66
65
  if (options.astFactory) {
67
66
  defaultStrategy.setASTFactory(options.astFactory);
@@ -67,6 +67,32 @@ var Multimap = (function () {
67
67
  return this;
68
68
  };
69
69
 
70
+ /**
71
+ * @return {Array} all the keys in the map
72
+ */
73
+ Multimap.prototype.keys = function () {
74
+ if (this._map)
75
+ return makeIterator(this._.keys());
76
+
77
+ return makeIterator(Object.keys(this._));
78
+ };
79
+
80
+ function makeIterator(iterator) {
81
+ if (Array.isArray(iterator)) {
82
+ var nextIndex = 0;
83
+
84
+ return {
85
+ next: function () {
86
+ return nextIndex < iterator.length ?
87
+ { value: iterator[nextIndex++], done: false } :
88
+ { done: true };
89
+ }
90
+ };
91
+ }
92
+
93
+ return iterator;
94
+ }
95
+
70
96
  return Multimap;
71
97
  })();
72
98
 
@@ -15,7 +15,10 @@ let allAssociations = {};
15
15
  let allAssociationSets = {};
16
16
  let allComplexTypes = {};
17
17
  let allComplexTypeDocs = {};
18
+ let allComplexTypeNamespaces = {};
18
19
  let allInheritedComplexTypes = {};
20
+ let allowedNamespaces = [];
21
+ let allowAllNamespaces = false;
19
22
  let messages = require("./message").getMessages();
20
23
  let common = require("./common");
21
24
  let versionInfo = require('../../package.json').version;
@@ -57,9 +60,49 @@ function _initialize() {
57
60
  allAssociationSets = {};
58
61
  allComplexTypes = {};
59
62
  allComplexTypeDocs = {};
63
+ allComplexTypeNamespaces = {};
60
64
  allInheritedComplexTypes = {};
65
+ allowedNamespaces = [];
66
+ allowAllNamespaces = false;
61
67
  }
62
68
 
69
+ // Function to extract allowed namespace attributes from given set of attributes
70
+ function namespaceAttributeFilter(attributes) {
71
+ let namespaceAttributes = allowAllNamespaces
72
+ ? Object.keys(attributes).filter((attr) => attr.includes(':'))
73
+ : Object.keys(attributes).filter(
74
+ (attr) =>
75
+ attr.includes(':') &&
76
+ allowedNamespaces.includes(attr.split(':')[0]));
77
+
78
+
79
+ namespaceAttributes = namespaceAttributes.map(attribute => {
80
+ const index = attribute.indexOf(':');
81
+ let namespace = attribute.slice(0, index);
82
+ let name = attribute.slice(index + 1);
83
+
84
+ name = name.replace(/-/g, '.');
85
+
86
+ let formattedAttribute = {};
87
+ formattedAttribute[`${namespace}.${name}`] = _replaceSpecialCharacters(attributes[attribute]);
88
+ return formattedAttribute;
89
+ });
90
+
91
+ return namespaceAttributes;
92
+ }
93
+
94
+ //Function to generate CSN for namespace attributes
95
+ function _generateNamespaceAttributes(attributes, isBefore) {
96
+ let csn = "";
97
+ attributes.forEach((attr) => {
98
+ let key = Object.keys(attr)[0];
99
+ if (isBefore) csn = csn + ',\n';
100
+ csn = csn + `"@${key}":"${attr[key]}"`;
101
+ if (!isBefore) csn = csn + ',\n';
102
+ });
103
+
104
+ return csn;
105
+ }
63
106
  function _isValidEDMX(jsonObj) {
64
107
  let isValid = false;
65
108
  let edmx;
@@ -300,20 +343,20 @@ function _extractAllFunctionImports(functionImports, serviceNamespaceParam)
300
343
  }
301
344
  }
302
345
 
303
- function _removeCarriageReturn(text) {
304
- return text.replace(/(?:\\[rn]|[\r\n]+)+/gm, "\\n").replace(/\s+/g, ' ').trim();
346
+ function _replaceSpecialCharacters(text) {
347
+ return text.replace(/(?:\\[rn]|[\r\n]+)+/gm, "\\n").replace(/\s+/g, ' ').replace(/"/g, "&quot;").trim();
305
348
  }
306
349
 
307
350
  // to parse the documentation tag
308
351
  function _parseDocumentationTag(documentedContent) {
309
352
  let documentation = "";
310
353
  if (documentedContent.Summary && documentedContent.Summary._text) {
311
- documentation = _removeCarriageReturn(documentedContent.Summary._text);
354
+ documentation = _replaceSpecialCharacters(documentedContent.Summary._text);
312
355
  }
313
356
  if (documentedContent.LongDescription && documentedContent.LongDescription._text) {
314
357
  if (documentedContent.Summary)
315
358
  documentation += "\\n\\n";
316
- documentation += _removeCarriageReturn(documentedContent.LongDescription._text);
359
+ documentation += _replaceSpecialCharacters(documentedContent.LongDescription._text);
317
360
  }
318
361
  return documentation;
319
362
  }
@@ -322,10 +365,12 @@ function _extractComplexType(complexType, serviceNamespaceParam) {
322
365
  let complexTypeKey = "";
323
366
  let baseType = "";
324
367
  let properties;
368
+ let namespaceAttributes = {};
325
369
  Object.keys(complexType).forEach((key) => {
326
370
  if (key === "_attributes") {
327
371
  complexTypeKey =
328
372
  serviceNamespaceParam + "." + complexType[key].Name;
373
+ namespaceAttributes = namespaceAttributeFilter(complexType[key]);
329
374
  baseType = complexType[key].BaseType;
330
375
  } else if (key === "Property") {
331
376
  properties = complexType.Property;
@@ -337,6 +382,9 @@ function _extractComplexType(complexType, serviceNamespaceParam) {
337
382
  if (complexTypeKey && baseType) {
338
383
  allInheritedComplexTypes[complexTypeKey] = baseType;
339
384
  }
385
+ if (namespaceAttributes.length) {
386
+ allComplexTypeNamespaces[complexTypeKey] = namespaceAttributes;
387
+ }
340
388
  }
341
389
 
342
390
  function _extractAllComplexTypes(complexTypes, serviceNamespaceParam) {
@@ -361,7 +409,8 @@ function _getServiceEntityProperty(
361
409
  displayFormat,
362
410
  isKey,
363
411
  documentation,
364
- isCollection
412
+ isCollection,
413
+ allowedNamespaceAttributes = -1
365
414
  ) {
366
415
  let cdsDataType = null;
367
416
  let hasInvalidPrecision = false;
@@ -427,6 +476,10 @@ function _getServiceEntityProperty(
427
476
  propertyJson = propertyJson + ',\n"doc":"' + documentation + '"';
428
477
  }
429
478
 
479
+ if (allowedNamespaceAttributes !== -1) {
480
+ propertyJson += _generateNamespaceAttributes(allowedNamespaceAttributes, true);
481
+ }
482
+
430
483
  if(propertyName)
431
484
  propertyJson = propertyJson + "\n}";
432
485
  return propertyJson;
@@ -437,6 +490,9 @@ function _getServiceComplexType(complexTypeKey, complexType) {
437
490
  let complexTypeProperty;
438
491
  let i;
439
492
  complexTypeCSN = complexTypeCSN + '"kind": "type",\n';
493
+ if(allComplexTypeNamespaces[complexTypeKey]) {
494
+ complexTypeCSN += _generateNamespaceAttributes(allComplexTypeNamespaces[complexTypeKey], false);
495
+ }
440
496
  if (allComplexTypeDocs[complexTypeKey])
441
497
  complexTypeCSN = complexTypeCSN + '"doc":' + `"${allComplexTypeDocs[complexTypeKey]}",` + "\n";
442
498
  complexTypeCSN = complexTypeCSN + '"elements": {\n';
@@ -447,6 +503,10 @@ function _getServiceComplexType(complexTypeKey, complexType) {
447
503
  complexTypeProperty = complexType[i]._attributes;
448
504
  if(complexType[i].Documentation)
449
505
  complexTypeProperty.doc = _parseDocumentationTag(complexType[i].Documentation);
506
+
507
+ let namespaceAttributes = namespaceAttributeFilter(complexTypeProperty)
508
+ const complexTypePropertyNamespace = namespaceAttributes.length ? namespaceAttributes : -1
509
+
450
510
  complexTypeCSN =
451
511
  complexTypeCSN +
452
512
  _getServiceEntityProperty(
@@ -458,7 +518,8 @@ function _getServiceComplexType(complexTypeKey, complexType) {
458
518
  complexTypeProperty["sap:display-format"],
459
519
  false,
460
520
  complexTypeProperty.doc,
461
- -1
521
+ -1,
522
+ complexTypePropertyNamespace
462
523
  );
463
524
  if (i !== complexType.length - 1) {
464
525
  complexTypeCSN = complexTypeCSN + ",\n";
@@ -471,6 +532,10 @@ function _getServiceComplexType(complexTypeKey, complexType) {
471
532
  complexTypeProperty = complexType._attributes;
472
533
  if(complexType.Documentation)
473
534
  complexTypeProperty.doc = _parseDocumentationTag(complexType.Documentation);
535
+
536
+ let namespaceAttributes = namespaceAttributeFilter(complexTypeProperty);
537
+ const complexTypePropertyNamespace = namespaceAttributes.length ? namespaceAttributes : -1;
538
+
474
539
  complexTypeCSN =
475
540
  complexTypeCSN +
476
541
  _getServiceEntityProperty(
@@ -482,7 +547,8 @@ function _getServiceComplexType(complexTypeKey, complexType) {
482
547
  complexTypeProperty["sap:display-format"],
483
548
  false,
484
549
  complexTypeProperty.doc,
485
- -1
550
+ -1,
551
+ complexTypePropertyNamespace
486
552
  );
487
553
  }
488
554
  }
@@ -527,6 +593,10 @@ function _parseParameter(parameter)
527
593
  let isCollection = -1;
528
594
  if(parameter.Documentation)
529
595
  doc = _parseDocumentationTag(parameter.Documentation);
596
+
597
+ let namespaceAttributes = namespaceAttributeFilter(parameter._attributes);
598
+ const parameterNamespaceAttributes = namespaceAttributes.length ? namespaceAttributes : -1;
599
+
530
600
  let type = parameter["_attributes"].Type;
531
601
  if(type.substring(0,10) === 'Collection')
532
602
  {
@@ -541,7 +611,8 @@ function _parseParameter(parameter)
541
611
  parameter["_attributes"]["sap:display-format"],
542
612
  false,
543
613
  doc,
544
- isCollection);
614
+ isCollection,
615
+ parameterNamespaceAttributes);
545
616
  return csn;
546
617
  }
547
618
 
@@ -605,7 +676,7 @@ function _getFunctionImport(functionImport,isBounded) {
605
676
  }
606
677
  if(functionImport[4] !== -1)
607
678
  {
608
- csn = csn + ',\n "doc": "' + functionImport[4] + '"';
679
+ csn = csn + ',\n "doc": "' + _replaceSpecialCharacters(functionImport[4]) + '"';
609
680
  }
610
681
 
611
682
  csn = csn + "\n }";
@@ -640,6 +711,8 @@ function _parseEntityAttributes(attributes) {
640
711
  entityAttributes.Name = attributes.Name;
641
712
  entityAttributes.BaseType = attributes.BaseType;
642
713
  entityAttributes.Abstract = attributes.Abstract;
714
+ entityAttributes.allowedNamespaceAttributes = namespaceAttributeFilter(attributes);
715
+
643
716
  return entityAttributes;
644
717
  }
645
718
 
@@ -661,6 +734,9 @@ function _parseEntityKeys(keys) {
661
734
 
662
735
  function _getPropertyAttributes(propAttributes) {
663
736
  let propOthers = [];
737
+
738
+ let namespaceAttributes = namespaceAttributeFilter(propAttributes)
739
+
664
740
  propOthers.push(propAttributes.Type);
665
741
  if (propAttributes.MaxLength) {
666
742
  propOthers.push(propAttributes.MaxLength);
@@ -690,6 +766,13 @@ function _getPropertyAttributes(propAttributes) {
690
766
  }else{
691
767
  propOthers.push(-1);
692
768
  }
769
+
770
+ if (namespaceAttributes.length) {
771
+ propOthers.push(namespaceAttributes);
772
+ } else {
773
+ propOthers.push(-1);
774
+ }
775
+
693
776
  return propOthers;
694
777
  }
695
778
 
@@ -758,7 +841,8 @@ function _generateCSNEntityKeys(entityKeysList, entityPropertiesMap) {
758
841
  propAttributes[4],
759
842
  true,
760
843
  propAttributes[5],
761
- -1
844
+ -1,
845
+ propAttributes[6]
762
846
  );
763
847
  if (i !== entityKeysList.length - 1) {
764
848
  csnEntity = csnEntity + ",\n";
@@ -796,7 +880,8 @@ function _generateCSNEntityProperties(entityKeysList, entityPropertiesMap) {
796
880
  propAttributes[4],
797
881
  false,
798
882
  propAttributes[5],
799
- -1
883
+ -1,
884
+ propAttributes[6]
800
885
  );
801
886
  if (i !== entityProperties.length - 1) {
802
887
  csnEntity = csnEntity + ",\n";
@@ -1078,6 +1163,7 @@ function _getServiceEntityNavigationProperty(navPropAttributes, mockServerUc) {
1078
1163
  let navPropName;
1079
1164
  let relationshipName;
1080
1165
  let navPropDoc;
1166
+ let allowedNamespaceAttributes = namespaceAttributeFilter(navPropAttributes);
1081
1167
  // var fromRole;
1082
1168
  let toRole;
1083
1169
  if (!navPropAttributes) {
@@ -1090,6 +1176,9 @@ function _getServiceEntityNavigationProperty(navPropAttributes, mockServerUc) {
1090
1176
  navPropDoc = navPropAttributes.doc;
1091
1177
 
1092
1178
  csn = csn + '"' + navPropName + '": {\n';
1179
+ if(allowedNamespaceAttributes.length) {
1180
+ csn += _generateNamespaceAttributes(allowedNamespaceAttributes, false);
1181
+ }
1093
1182
  // if documentatin exists for navigation property
1094
1183
  if (navPropDoc) {
1095
1184
  csn = csn + '"doc":' + `"Please add an ON condition\\n${navPropDoc}",\n`;
@@ -1156,6 +1245,7 @@ function _constructServiceEntity(
1156
1245
  entityPropertiesMap,
1157
1246
  entityNavigationPropertiesMap,
1158
1247
  entityAttributes,
1248
+ ignorePersistenceSkip,
1159
1249
  mockServerUc,
1160
1250
  documentation
1161
1251
  ) {
@@ -1165,12 +1255,20 @@ function _constructServiceEntity(
1165
1255
  let csnProperties;
1166
1256
  let hasProperties;
1167
1257
  csnEntity = csnEntity + '"kind": "entity",\n';
1258
+ if (ignorePersistenceSkip === false) {
1259
+ csnEntity = csnEntity + '"@cds.persistence.skip": true,\n';
1260
+ }
1168
1261
  if (
1169
1262
  entityAttributes.Abstract &&
1170
1263
  entityAttributes.Abstract.toUpperCase() === "TRUE"
1171
1264
  ) {
1172
1265
  csnEntity = csnEntity + '"abstract": true,\n';
1173
1266
  }
1267
+
1268
+ if(entityAttributes.allowedNamespaceAttributes.length)
1269
+ {
1270
+ csnEntity += _generateNamespaceAttributes(entityAttributes.allowedNamespaceAttributes, false);
1271
+ }
1174
1272
  // if documentation exists for the entity
1175
1273
  if (documentation) {
1176
1274
  csnEntity = csnEntity + `"doc": "${documentation}",` + '\n';
@@ -1230,6 +1328,7 @@ function _parseServiceEntity(
1230
1328
  serviceNamespaceParam,
1231
1329
  entityName,
1232
1330
  entity,
1331
+ ignorePersistenceSkip,
1233
1332
  mockServerUc
1234
1333
  ) {
1235
1334
  let entityAttributes;
@@ -1278,6 +1377,7 @@ function _parseServiceEntity(
1278
1377
  entityPropertiesMap,
1279
1378
  entityNavigationPropertiesMap,
1280
1379
  entityAttributes,
1380
+ ignorePersistenceSkip,
1281
1381
  mockServerUc,
1282
1382
  documentation
1283
1383
  );
@@ -1318,6 +1418,7 @@ function _getEntitesWithNamesFromEntitySets(
1318
1418
  function _getServiceEntitites(
1319
1419
  serviceNamespaceParam,
1320
1420
  entityJson = [],
1421
+ ignorePersistenceSkip,
1321
1422
  mockServerUc
1322
1423
  ) {
1323
1424
  const entities = Array.isArray(entityJson) ? entityJson : [entityJson];
@@ -1335,6 +1436,7 @@ function _getServiceEntitites(
1335
1436
  serviceNamespaceParam,
1336
1437
  entityName,
1337
1438
  entityWithName.entity,
1439
+ ignorePersistenceSkip,
1338
1440
  mockServerUc
1339
1441
  )
1340
1442
  )
@@ -1348,6 +1450,7 @@ function _getServiceEntitites(
1348
1450
  function _generateEDMXJSON2CSN(
1349
1451
  jsonObj,
1350
1452
  serviceNamespaceParam,
1453
+ ignorePersistenceSkip,
1351
1454
  mockServerUc
1352
1455
  ) {
1353
1456
  const csn = {};
@@ -1422,6 +1525,7 @@ function _generateEDMXJSON2CSN(
1422
1525
  _getServiceEntitites(
1423
1526
  serviceNamespaceParam,
1424
1527
  entityJson,
1528
+ ignorePersistenceSkip,
1425
1529
  mockServerUc
1426
1530
  )
1427
1531
  );
@@ -1437,17 +1541,32 @@ function _generateEDMXJSON2CSN(
1437
1541
 
1438
1542
  function getEdmxv2CSN(
1439
1543
  edmx2jsonModel,
1440
- mockServerUc
1544
+ ignorePersistenceSkip,
1545
+ mockServerUc,
1546
+ context
1441
1547
  ) {
1442
1548
  let csnDataModel;
1443
1549
  let isValid;
1444
1550
  _initialize();
1551
+ if (!context.include_all_namespaces && context.namespaces.length) {
1552
+ allowedNamespaces = allowedNamespaces.concat(context.namespaces)
1553
+ }
1554
+ else if(context.include_all_namespaces) {
1555
+ allowAllNamespaces = true;
1556
+ }
1557
+
1445
1558
  isValid = _validateEDMX(edmx2jsonModel);
1446
1559
  if (isValid) {
1447
1560
  serviceNamespace = _getServiceNameSpace(edmx2jsonModel);
1561
+ let namespaceAlias = edmx2jsonModel["edmx:Edmx"]["edmx:DataServices"].Schema._attributes.Alias;
1562
+ // replace the namespace alias value with original namespace value
1563
+ if (namespaceAlias) {
1564
+ edmx2jsonModel = common.replaceAliasValue(JSON.stringify(edmx2jsonModel), serviceNamespace, namespaceAlias);
1565
+ }
1448
1566
  csnDataModel = _generateEDMXJSON2CSN(
1449
1567
  edmx2jsonModel,
1450
1568
  serviceNamespace,
1569
+ ignorePersistenceSkip,
1451
1570
  mockServerUc
1452
1571
  );
1453
1572
  }