@sap/cds-dk 6.5.2 → 6.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/bin/activate.js +7 -0
- package/bin/add.js +1 -2
- package/bin/build/all.js +14 -9
- package/bin/cds.js +11 -8
- package/bin/compile/index.js +13 -3
- package/bin/env.js +16 -25
- package/bin/extend.js +8 -0
- package/bin/init.js +0 -3
- package/bin/login.js +3 -7
- package/bin/logout.js +2 -7
- package/bin/watch.js +4 -5
- package/lib/client/activate.js +1 -1
- package/lib/client/helper/errors.js +4 -1
- package/lib/client/params.js +4 -3
- package/lib/client/pull.js +31 -5
- package/lib/client/push.js +3 -3
- package/lib/client/settings_manager.js +6 -6
- package/lib/client/subscription.js +1 -1
- package/lib/compile/asyncapi/channels.js +22 -0
- package/lib/compile/asyncapi/components/messageTraits/index.js +89 -0
- package/lib/compile/asyncapi/components/messages/index.js +150 -0
- package/lib/compile/asyncapi/components/schemas/annotations.js +13 -0
- package/lib/compile/asyncapi/components/schemas/array.js +8 -0
- package/lib/compile/asyncapi/components/schemas/cache.js +14 -0
- package/lib/compile/asyncapi/components/schemas/definition.js +187 -0
- package/lib/compile/asyncapi/components/schemas/enum.js +16 -0
- package/lib/compile/asyncapi/components/schemas/examples.js +10 -0
- package/lib/compile/asyncapi/components/schemas/index.js +14 -0
- package/lib/compile/asyncapi/components/schemas/localized.js +29 -0
- package/lib/compile/asyncapi/components/schemas/primitiveElement.js +41 -0
- package/lib/compile/asyncapi/components/schemas/ref.js +45 -0
- package/lib/compile/asyncapi/components/schemas/utils.js +108 -0
- package/lib/compile/asyncapi/index.js +226 -0
- package/lib/compile/asyncapi/message.js +13 -0
- package/lib/compile/asyncapi/utils.js +27 -0
- package/lib/compile/index.js +1 -0
- package/lib/compile/openapi/csdl2openapi.js +42 -18
- package/lib/import/message.js +4 -1
- package/lib/import/odata/metadataconverter/MetadataConverter.js +8 -3
- package/lib/import/odata/v2parser.js +131 -50
- package/lib/import/odata/v4parser.js +292 -112
- package/lib/import/openapi/importOpenAPI.js +14 -14
- package/lib/init/constants.js +1 -1
- package/lib/init/index.js +11 -21
- package/lib/init/template/_merging/registry-mta.js +15 -26
- package/lib/init/template/approuter/files/package.json +2 -2
- package/lib/init/template/approuter/index.js +6 -12
- package/lib/init/template/auditlog/files/auditlog.yaml +4 -1
- package/lib/init/template/auditlog/index.js +23 -8
- package/lib/init/template/cf-manifest/index.js +4 -14
- package/lib/init/template/connectivity/files/connectivity-proxy-info.yaml +2 -6
- package/lib/init/template/connectivity/files/values.yaml.hbs +5 -8
- package/lib/init/template/connectivity/index.js +2 -9
- package/lib/init/template/data/index.js +0 -4
- package/lib/init/template/destinations/files/destination.yaml +4 -1
- package/lib/init/template/destinations/index.js +25 -10
- package/lib/init/template/enterprise-messaging/files/event-mesh.yaml +4 -1
- package/lib/init/template/enterprise-messaging/files/values.yaml +1 -2
- package/lib/init/template/enterprise-messaging/index.js +28 -20
- package/lib/init/template/extensibility/index.js +23 -31
- package/lib/init/template/hana/files/hana.yaml +4 -1
- package/lib/init/template/hana/index.js +44 -24
- package/lib/init/template/helm/chart/templates/_helpers.tpl +12 -0
- package/lib/init/template/helm/chart/values.root.schema.json +40 -0
- package/lib/init/template/helm/chart/values.schema.json +32 -69
- package/lib/init/template/helm/index.js +26 -16
- package/lib/init/template/helm/subcharts/content-deployment/templates/_helpers.tpl +13 -26
- package/lib/init/template/helm/subcharts/content-deployment/templates/job.yaml +3 -3
- package/lib/init/template/helm/subcharts/content-deployment/templates/service-account.yaml +2 -0
- package/lib/init/template/helm/subcharts/content-deployment/templates/service-binding.yaml +3 -3
- package/lib/init/template/helm/subcharts/content-deployment/templating.md +37 -0
- package/lib/init/template/helm/subcharts/content-deployment/values.md +182 -185
- package/lib/init/template/helm/subcharts/content-deployment/values.schema.json +18 -22
- package/lib/init/template/helm/subcharts/content-deployment/values.yaml +2 -0
- package/lib/init/template/helm/subcharts/service-instance/Chart.yaml +5 -0
- package/lib/init/template/helm/subcharts/service-instance/templates/_helpers.tpl +65 -0
- package/lib/init/template/helm/subcharts/service-instance/templates/serviceinstance.yaml +23 -0
- package/lib/init/template/helm/subcharts/service-instance/templating.md +18 -0
- package/lib/init/template/helm/subcharts/service-instance/values-lint.yaml +2 -0
- package/lib/init/template/helm/subcharts/service-instance/values.md +186 -0
- package/lib/init/template/helm/subcharts/service-instance/values.schema.json +102 -0
- package/lib/init/template/helm/subcharts/service-instance/values.yaml +15 -0
- package/lib/init/template/html5-repo/files/html5-apps-deployer-configmap.yaml +2 -2
- package/lib/init/template/html5-repo/files/html5-apps-repo-host.yaml +4 -1
- package/lib/init/template/html5-repo/index.js +30 -21
- package/lib/init/template/java/index.js +3 -6
- package/lib/init/template/kibana-logging/index.js +7 -10
- package/lib/init/template/lint/index.js +2 -3
- package/lib/init/template/mta/files/mta.yaml.hbs +4 -2
- package/lib/init/template/mta/index.js +7 -11
- package/lib/init/template/mtx/index.js +0 -5
- package/lib/init/template/multitenancy/files/java/package.json +16 -7
- package/lib/init/template/multitenancy/files/mta.yaml.hbs +11 -3
- package/lib/init/template/multitenancy/files/saas-registry-secret.yaml +9 -0
- package/lib/init/template/multitenancy/files/saas-registry.yaml +4 -17
- package/lib/init/template/multitenancy/files/service-manager.yaml +4 -1
- package/lib/init/template/multitenancy/files/values.yaml.hbs +15 -3
- package/lib/init/template/multitenancy/index.js +56 -31
- package/lib/init/template/nodejs/index.js +4 -7
- package/lib/init/template/notebook/index.js +1 -3
- package/lib/init/template/pipeline/index.js +2 -5
- package/lib/init/template/samples/index.js +6 -11
- package/lib/init/template/templateBase.js +10 -17
- package/lib/init/template/toggles/index.js +2 -6
- package/lib/init/template/xsuaa/files/values.yaml.hbs +0 -1
- package/lib/init/template/xsuaa/files/xsuaa.yaml +4 -1
- package/lib/init/template/xsuaa/index.js +27 -23
- package/lib/init/types.d.ts +0 -81
- package/lib/init/util/merge.js +23 -25
- package/lib/init/util/mvnArchetypeUtil.js +34 -2
- package/lib/init/util/projectReader.js +27 -24
- package/lib/lint/Linter.js +31 -13
- package/lib/watch/livereload-server.js +29 -17
- package/lib/watch/node-watch.js +51 -49
- package/npm-shrinkwrap.json +548 -467
- package/package.json +4 -4
- package/readme.md +5 -0
- package/lib/init/template/connectivity/files/connectivity-binding.yaml +0 -9
- package/lib/init/template/connectivity/files/connectivity.yaml +0 -1
- package/lib/init/template/multitenancy/files/xsuaa.yaml +0 -1
- /package/lib/init/template/hana/files/{chart.yaml → hana-deployer.yaml} +0 -0
- /package/lib/init/template/html5-repo/files/{chart.yaml → html5-apps-deployer.yaml} +0 -0
- /package/lib/init/template/multitenancy/files/{chart.yaml → sidecar.yaml} +0 -0
|
@@ -12,7 +12,6 @@ const ignoreObjects = ["$Reference"]; // add all the objects that needs to be ig
|
|
|
12
12
|
const validEdmDatatypes = ["Edm.DateTimeOffset"];
|
|
13
13
|
const { warn } = require("../../util/term");
|
|
14
14
|
const MetadataConverterFactory = require("./metadataconverter/MetadataConverterFactory");
|
|
15
|
-
const cds = require('../../cds');
|
|
16
15
|
|
|
17
16
|
const edmxncdsdatatype = {
|
|
18
17
|
"Edm.String": "cds.LargeString",
|
|
@@ -43,6 +42,26 @@ const edmxncdsdatatype = {
|
|
|
43
42
|
"Edm.DateTimeOffset_a": "cds.Timestamp",
|
|
44
43
|
};
|
|
45
44
|
|
|
45
|
+
const extendedPrimitiveTypes = [
|
|
46
|
+
"Edm.Duration",
|
|
47
|
+
"Edm.Geography",
|
|
48
|
+
"Edm.GeographyPoint",
|
|
49
|
+
"Edm.GeographyLineString",
|
|
50
|
+
"Edm.GeographyPolygon",
|
|
51
|
+
"Edm.GeographyMultiPoint",
|
|
52
|
+
"Edm.GeographyMultiLineString",
|
|
53
|
+
"Edm.GeographyMultiPolygon",
|
|
54
|
+
"Edm.GeographyCollection",
|
|
55
|
+
"Edm.Geometry",
|
|
56
|
+
"Edm.GeometryPoint",
|
|
57
|
+
"Edm.GeometryLineString",
|
|
58
|
+
"Edm.GeometryPolygon",
|
|
59
|
+
"Edm.GeometryMultiPoint",
|
|
60
|
+
"Edm.GeometryMultiLineString",
|
|
61
|
+
"Edm.GeometryMultiPolygon",
|
|
62
|
+
"Edm.GeometryCollection"
|
|
63
|
+
];
|
|
64
|
+
|
|
46
65
|
const known_vocabularies = {
|
|
47
66
|
'Org.OData.Authorization.V1': 'Authorization',
|
|
48
67
|
'Org.OData.Aggregation.V1': 'Aggregation',
|
|
@@ -122,7 +141,7 @@ function _hasEntityContainer(jsonObj, parserContext) {
|
|
|
122
141
|
jsonObj[parserContext.namespace][parserContext.jsonEntityContainerName] instanceof Object
|
|
123
142
|
) {
|
|
124
143
|
return true;
|
|
125
|
-
}
|
|
144
|
+
}
|
|
126
145
|
} catch (err) {
|
|
127
146
|
throw new Error(messages.MISSING_ENTITY_CONTAINER);
|
|
128
147
|
}
|
|
@@ -138,11 +157,11 @@ function _includeExternalNamespaceAnnotation(source, target) {
|
|
|
138
157
|
|
|
139
158
|
function _addNotNull(property, isCollection) {
|
|
140
159
|
if (isCollection) property.items["notNull"] = true;
|
|
141
|
-
else property["notNull"] = true;
|
|
160
|
+
else property["notNull"] = true;
|
|
142
161
|
}
|
|
143
162
|
|
|
144
163
|
function _typeWithCollections(property, type, isCollection) {
|
|
145
|
-
if (isCollection
|
|
164
|
+
if (isCollection) {
|
|
146
165
|
let typeKeys = Object.keys(type);
|
|
147
166
|
for (let i = 0; i < typeKeys.length; i++) {
|
|
148
167
|
if (typeKeys[i].startsWith("@")) {
|
|
@@ -164,13 +183,13 @@ function generatePropertyCsn(propertyType, isPrimaryKey) {
|
|
|
164
183
|
// primary key cannot be of type Collection
|
|
165
184
|
if (propertyType.$Collection)
|
|
166
185
|
throw new Error(messages.COLLECTION_IN_KEY);
|
|
167
|
-
if (propertyType.$Nullable
|
|
186
|
+
if (propertyType.$Nullable) {
|
|
168
187
|
console.log(warn("Expected key element to be not nullable"));
|
|
169
188
|
}
|
|
170
189
|
typeProperties["notNull"] = true;
|
|
171
190
|
}
|
|
172
191
|
else {
|
|
173
|
-
if ((propertyType.$Nullable
|
|
192
|
+
if ((!propertyType.$Nullable) && (propertyType.$Kind !== 'TypeDefinition')) {
|
|
174
193
|
typeProperties["notNull"] = true;
|
|
175
194
|
}
|
|
176
195
|
}
|
|
@@ -221,9 +240,13 @@ function generatePropertyCsn(propertyType, isPrimaryKey) {
|
|
|
221
240
|
typeProperties["@odata.Type"] = propertyType.$Type;
|
|
222
241
|
}
|
|
223
242
|
}
|
|
224
|
-
|
|
225
243
|
_typeWithCollections(property, typeProperties, propertyType.$Collection);
|
|
226
244
|
|
|
245
|
+
if (propertyType.$DefaultValue) {
|
|
246
|
+
if (propertyType.$Collection) console.log(warn("Type with Collection cannot have DefaultValue"));
|
|
247
|
+
_addDefaultValueObject(property, propertyType.$DefaultValue);
|
|
248
|
+
}
|
|
249
|
+
|
|
227
250
|
return property;
|
|
228
251
|
}
|
|
229
252
|
|
|
@@ -233,6 +256,10 @@ function _generateComplexTypePropertyCsn(propertyType) {
|
|
|
233
256
|
_typeWithCollections(property, type, propertyType.$Collection);
|
|
234
257
|
if (!propertyType.$Nullable) _addNotNull(property, propertyType.$Collection);
|
|
235
258
|
|
|
259
|
+
if (propertyType.$DefaultValue && !propertyType.$Collection) {
|
|
260
|
+
_addDefaultValueObject(property, propertyType.$DefaultValue);
|
|
261
|
+
}
|
|
262
|
+
|
|
236
263
|
return property;
|
|
237
264
|
}
|
|
238
265
|
|
|
@@ -243,6 +270,7 @@ function _generateTypeDefinitionPropertyCsn(propertyType) {
|
|
|
243
270
|
_includeExternalNamespaceAnnotation(propertyType, property);
|
|
244
271
|
_typeWithCollections(property, type, propertyType.$Collection);
|
|
245
272
|
if (!propertyType.$Nullable) _addNotNull(property, propertyType.$Collection);
|
|
273
|
+
// Verify: Can DefaultValue be present here?
|
|
246
274
|
|
|
247
275
|
return property;
|
|
248
276
|
}
|
|
@@ -342,6 +370,10 @@ function _generateCSNForEntityType(ignorePersistenceSkip, mockServerUc, parserCo
|
|
|
342
370
|
let j;
|
|
343
371
|
let propertyType;
|
|
344
372
|
let enumType = {};
|
|
373
|
+
const entityTypeNames = parserContext.entityTypes.map(elementObject => {
|
|
374
|
+
return Object.keys(elementObject)[0];
|
|
375
|
+
});
|
|
376
|
+
|
|
345
377
|
parserContext.entityTypes.forEach(element => {
|
|
346
378
|
let key = Object.keys(element)[0];
|
|
347
379
|
let baseType = element[key].$BaseType;
|
|
@@ -364,13 +396,18 @@ function _generateCSNForEntityType(ignorePersistenceSkip, mockServerUc, parserCo
|
|
|
364
396
|
// inheritance
|
|
365
397
|
if (baseType) {
|
|
366
398
|
entityCsn[key].includes = [];
|
|
367
|
-
|
|
368
|
-
|
|
399
|
+
if (entityTypeNames.includes(baseType)) {
|
|
400
|
+
entityCsn[key].includes.push(baseType);
|
|
401
|
+
}
|
|
402
|
+
else if (parserContext.entitySetToEntityTypeMap && parserContext.entitySetToEntityTypeMap.get(baseType)) {
|
|
369
403
|
baseType = _getBaseTypeEntityName(baseType, parserContext);
|
|
404
|
+
entityCsn[key].includes.push(baseType);
|
|
405
|
+
} else {
|
|
406
|
+
delete entityCsn[key].includes;
|
|
407
|
+
throw new Error(messages.UNRESOLVED_TYPE + `'${baseType}' in element: '${element}'.`);
|
|
370
408
|
}
|
|
371
|
-
entityCsn[key].includes.push(baseType);
|
|
372
409
|
if (!parserContext.entityTypeOpenEntries.includes(baseType)) parserContext.entityTypeOpenEntries.push(baseType);
|
|
373
|
-
}
|
|
410
|
+
}
|
|
374
411
|
if ((isAbstract || isOpenType) && !parserContext.entityTypeOpenEntries.includes(key)) {
|
|
375
412
|
parserContext.entityTypeOpenEntries.push(key);
|
|
376
413
|
}
|
|
@@ -412,8 +449,9 @@ function _generateCSNForEntityType(ignorePersistenceSkip, mockServerUc, parserCo
|
|
|
412
449
|
propertyType = element[key][property];
|
|
413
450
|
entityCsn[key].elements[property] = _generateTypeDefinitionPropertyCsn(propertyType);
|
|
414
451
|
} else {
|
|
415
|
-
let message = '"' + element[key][property].$Type + '" is not supported (in element:"' + property + '")';
|
|
416
|
-
console.log(warn(message));
|
|
452
|
+
// let message = '"' + element[key][property].$Type + '" is not supported (in element:"' + property + '")';
|
|
453
|
+
// console.log(warn(message));
|
|
454
|
+
throw new Error(messages.UNRESOLVED_TYPE + `'${element[key][property].$Type}' in element: '${property}'.`);
|
|
417
455
|
}
|
|
418
456
|
}
|
|
419
457
|
}
|
|
@@ -528,6 +566,7 @@ function _collectEnumType(schemaDataList, parserContext) {
|
|
|
528
566
|
}
|
|
529
567
|
|
|
530
568
|
function _generateCSNForEnumType(schemaData, parserContext) {
|
|
569
|
+
const nonMemberList = ["$Kind", "$Type", "$UnderlyingType", "$IsFlags"];
|
|
531
570
|
let enumCsn = {};
|
|
532
571
|
let eTypes;
|
|
533
572
|
eTypes = _collectEnumType(schemaData, parserContext);
|
|
@@ -536,15 +575,19 @@ function _generateCSNForEnumType(schemaData, parserContext) {
|
|
|
536
575
|
enumCsn[element].kind = 'type';
|
|
537
576
|
enumCsn[element]['@cds.external'] = true;
|
|
538
577
|
enumCsn[element].enum = {};
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
578
|
+
/**
|
|
579
|
+
* If UnderlyingType not specified, default is Edm.Int32 --> cds.Integer
|
|
580
|
+
*/
|
|
581
|
+
let underlyingType = eTypes[element].$UnderlyingType;
|
|
582
|
+
enumCsn[element].type = underlyingType ? edmxncdsdatatype[underlyingType] : 'cds.Integer';
|
|
583
|
+
|
|
584
|
+
if (!enumCsn[element].type || enumCsn[element].type !== "cds.Integer" ) {
|
|
585
|
+
throw new Error(messages.INVALID_ENUM_TYPE + `'${underlyingType}'`);
|
|
586
|
+
}
|
|
587
|
+
Object.keys(eTypes[element]).forEach(member => {
|
|
588
|
+
if (!nonMemberList.includes(member)) {
|
|
589
|
+
enumCsn[element].enum[member] = {};
|
|
590
|
+
enumCsn[element].enum[member].val = eTypes[element][member];
|
|
548
591
|
}
|
|
549
592
|
});
|
|
550
593
|
});
|
|
@@ -718,72 +761,93 @@ function _parseBounded(csnDefs, flag, parserContext) {
|
|
|
718
761
|
if (paramObj.$Collection && !paramType.items) {
|
|
719
762
|
csnDefs[boundedEntityName].actions[name].params[paramName] = {};
|
|
720
763
|
csnDefs[boundedEntityName].actions[name].params[paramName].items = paramType;
|
|
721
|
-
if(paramObj.$Nullable
|
|
764
|
+
if (!paramObj.$Nullable) {
|
|
722
765
|
csnDefs[boundedEntityName].actions[name].params[paramName].items["notNull"] = true;
|
|
723
766
|
}
|
|
724
767
|
} else {
|
|
725
768
|
csnDefs[boundedEntityName].actions[name].params[paramName] = paramType;
|
|
726
769
|
if (!paramType.items) {
|
|
727
|
-
if(paramObj.$Nullable
|
|
770
|
+
if (!paramObj.$Nullable) {
|
|
728
771
|
csnDefs[boundedEntityName].actions[name].params[paramName].notNull = true;
|
|
729
772
|
}
|
|
730
773
|
}
|
|
774
|
+
}
|
|
731
775
|
}
|
|
776
|
+
else {
|
|
777
|
+
// let message = '"' + paramObj.$Type + '" is not supported (in element:"' + name + '")';
|
|
778
|
+
// console.log(warn(message));
|
|
779
|
+
throw new Error(messages.UNRESOLVED_TYPE + `'${paramObj.$Type}' in element: '${name}'.`);
|
|
780
|
+
}
|
|
781
|
+
if (csnDefs[boundedEntityName].actions[name].params[paramName])
|
|
782
|
+
Object.assign(csnDefs[boundedEntityName].actions[name].params[paramName], annotations);
|
|
732
783
|
}
|
|
733
|
-
else {
|
|
734
|
-
let message = '"' + paramObj.$Type + '" is not supported (in element:"' + name + '")';
|
|
735
|
-
console.log(warn(message));
|
|
736
|
-
}
|
|
737
|
-
if (csnDefs[boundedEntityName].actions[name].params[paramName])
|
|
738
|
-
Object.assign(csnDefs[boundedEntityName].actions[name].params[paramName], annotations);
|
|
739
784
|
}
|
|
740
785
|
}
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
delete csnDefs[boundedEntityName].actions[name].params;
|
|
745
|
-
}
|
|
746
|
-
// add returns
|
|
747
|
-
if (obj[j].$ReturnType) {
|
|
748
|
-
let returnType = {};
|
|
749
|
-
let annotations = {};
|
|
750
|
-
// check if the return type is pre-defined, undefined or custom defined
|
|
751
|
-
if (edmxncdsdatatype[obj[j].$ReturnType.$Type] || edmxncdsdatatype[obj[j].$ReturnType.$Type + "_a"])
|
|
752
|
-
returnType = generatePropertyCsn(obj[j].$ReturnType, false);
|
|
753
|
-
else {
|
|
754
|
-
let type = _getDatatype(obj[j].$ReturnType.$Type, parserContext);
|
|
755
|
-
_includeExternalNamespaceAnnotation(obj[j].$ReturnType, annotations);
|
|
756
|
-
if (type) returnType["type"] = type;
|
|
786
|
+
// if parameters has no entries
|
|
787
|
+
if (csnDefs[boundedEntityName].actions[name].params && Object.keys(csnDefs[boundedEntityName].actions[name].params).length === 0) {
|
|
788
|
+
delete csnDefs[boundedEntityName].actions[name].params;
|
|
757
789
|
}
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
790
|
+
// add returns
|
|
791
|
+
if (obj[j].$ReturnType) {
|
|
792
|
+
let returnType = {};
|
|
793
|
+
let annotations = {};
|
|
794
|
+
let hasCdsTypeMapping = false;
|
|
795
|
+
// check if the return type is pre-defined, undefined or custom defined
|
|
796
|
+
if (edmxncdsdatatype[obj[j].$ReturnType.$Type] || edmxncdsdatatype[obj[j].$ReturnType.$Type + "_a"] ||
|
|
797
|
+
(!obj[j].$ReturnType.$Type && obj[j].$ReturnType.$MaxLength)
|
|
798
|
+
)
|
|
799
|
+
returnType = generatePropertyCsn(obj[j].$ReturnType, false);
|
|
800
|
+
else {
|
|
801
|
+
let type;
|
|
802
|
+
if (extendedPrimitiveTypes.includes(obj[j].$ReturnType.$Type)) {
|
|
803
|
+
hasCdsTypeMapping = true;
|
|
767
804
|
}
|
|
768
805
|
else {
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
806
|
+
type = _getDatatype(obj[j].$ReturnType.$Type, parserContext);
|
|
807
|
+
}
|
|
808
|
+
_includeExternalNamespaceAnnotation(obj[j].$ReturnType, annotations);
|
|
809
|
+
if (type) returnType["type"] = type;
|
|
810
|
+
if (!type && !hasCdsTypeMapping) {
|
|
811
|
+
throw new Error(messages.UNRESOLVED_TYPE + `'${obj[j].$ReturnType.$Type}'`);
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
if (Object.keys(returnType).length > 0) {
|
|
815
|
+
if (returnType.type || returnType.items.type) {
|
|
816
|
+
csnDefs[boundedEntityName].actions[name].returns = {};
|
|
817
|
+
// check if return type is a collection
|
|
818
|
+
if (obj[j].$ReturnType.$Collection && !returnType.items) {
|
|
819
|
+
csnDefs[boundedEntityName].actions[name].returns.items = returnType;
|
|
820
|
+
if (!obj[j].$ReturnType.$Nullable) {
|
|
821
|
+
csnDefs[boundedEntityName].actions[name].returns.items["notNull"] = true;
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
else {
|
|
825
|
+
csnDefs[boundedEntityName].actions[name].returns = returnType;
|
|
826
|
+
if (!returnType.items) {
|
|
827
|
+
if (!obj[j].$ReturnType.$Nullable){
|
|
828
|
+
csnDefs[boundedEntityName].actions[name].returns["notNull"] = true;
|
|
829
|
+
}
|
|
773
830
|
}
|
|
774
831
|
}
|
|
775
832
|
}
|
|
833
|
+
} else {
|
|
834
|
+
csnDefs[boundedEntityName].actions[name].returns = {};
|
|
835
|
+
if (obj[j].$ReturnType.$Collection && !returnType.items) {
|
|
836
|
+
csnDefs[boundedEntityName].actions[name].returns = { "@odata.Type": obj[j].$ReturnType.$Type };
|
|
837
|
+
csnDefs[boundedEntityName].actions[name].returns.items = { "type": "cds.String" };
|
|
838
|
+
}
|
|
839
|
+
else
|
|
840
|
+
csnDefs[boundedEntityName].actions[name].returns = { "type": "cds.String", "@odata.Type": obj[j].$ReturnType.$Type };
|
|
776
841
|
}
|
|
842
|
+
if (csnDefs[boundedEntityName].actions[name].returns)
|
|
843
|
+
Object.assign(csnDefs[boundedEntityName].actions[name].returns, annotations);
|
|
777
844
|
} else {
|
|
778
|
-
|
|
779
|
-
|
|
845
|
+
if (obj[j].$Kind === 'Function')
|
|
846
|
+
throw new Error(messages.NO_RETURN_TYPE + `'${name}'.`);
|
|
780
847
|
}
|
|
781
|
-
if (csnDefs[boundedEntityName].actions[name].returns)
|
|
782
|
-
Object.assign(csnDefs[boundedEntityName].actions[name].returns, annotations)
|
|
783
848
|
}
|
|
784
849
|
}
|
|
785
850
|
}
|
|
786
|
-
}
|
|
787
851
|
});
|
|
788
852
|
}
|
|
789
853
|
}
|
|
@@ -829,13 +893,18 @@ function _generateCSNForComplexType(schemaData, parserContext) {
|
|
|
829
893
|
isAbstract = cTypes[element].$Abstract;
|
|
830
894
|
isOpenType = cTypes[element].$OpenType;
|
|
831
895
|
if (baseType) {
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
896
|
+
if (parserContext.complexTypes[baseType]) {
|
|
897
|
+
complexCsn[element].includes = [];
|
|
898
|
+
complexCsn[element].includes.push(baseType);
|
|
899
|
+
if (!parserContext.complexTypeOpenEntries.includes(baseType)) parserContext.complexTypeOpenEntries.push(baseType);
|
|
900
|
+
}
|
|
901
|
+
else {
|
|
902
|
+
throw new Error(messages.UNRESOLVED_TYPE + `'${baseType}' in element: '${element}'.`);
|
|
903
|
+
}
|
|
835
904
|
}
|
|
836
905
|
if ((isAbstract || isOpenType) && !parserContext.complexTypeOpenEntries.includes(element)) {
|
|
837
906
|
parserContext.complexTypeOpenEntries.push(element);
|
|
838
|
-
}
|
|
907
|
+
}
|
|
839
908
|
Object.keys(cTypes[element]).forEach(property => { // cTypes[element][property].$Type.startsWith('Edm.')
|
|
840
909
|
if (cTypes[element][property] instanceof Object) {
|
|
841
910
|
if (!cTypes[element][property].$Type ||
|
|
@@ -854,8 +923,9 @@ function _generateCSNForComplexType(schemaData, parserContext) {
|
|
|
854
923
|
enumType = cTypes[element][property];
|
|
855
924
|
complexCsn[element].elements[property] = generatePropertyCsn(enumType, false);
|
|
856
925
|
} else {
|
|
857
|
-
let message = '"' + cTypes[element][property].$Type + '" is not supported (in element:"' + property + '")';
|
|
858
|
-
console.log(warn(message));
|
|
926
|
+
// let message = '"' + cTypes[element][property].$Type + '" is not supported (in element:"' + property + '")';
|
|
927
|
+
// console.log(warn(message));
|
|
928
|
+
throw new Error(messages.UNRESOLVED_TYPE + `'${cTypes[element][property].$Type}' in element: '${property}'.`);
|
|
859
929
|
}
|
|
860
930
|
} else if (property.startsWith("@")) {
|
|
861
931
|
complexCsn[element][property] = cTypes[element][property];
|
|
@@ -878,11 +948,16 @@ function _parseTypeDefinition(parserContext) {
|
|
|
878
948
|
typeDef[element] = {};
|
|
879
949
|
typeDef[element].kind = 'type';
|
|
880
950
|
typeDef[element]['@cds.external'] = true;
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
951
|
+
|
|
952
|
+
let underlyingType = parserContext.typeDefinitions[element].$UnderlyingType;
|
|
953
|
+
parserContext.typeDefinitions[element].$Type = underlyingType;
|
|
954
|
+
|
|
955
|
+
if (edmxncdsdatatype[underlyingType] ) {
|
|
884
956
|
propertyType = parserContext.typeDefinitions[element];
|
|
885
957
|
typeDef[element] = Object.assign(typeDef[element], generatePropertyCsn(propertyType, false));
|
|
958
|
+
if (typeDef[element].type === "cds.LargeString") typeDef[element].type = "cds.String";
|
|
959
|
+
} else {
|
|
960
|
+
throw new Error(messages.UNRESOLVED_TYPE + `'${underlyingType}'`);
|
|
886
961
|
}
|
|
887
962
|
});
|
|
888
963
|
return typeDef;
|
|
@@ -933,21 +1008,22 @@ function _parseUnbounded(schemaData, flag, parserContext) {
|
|
|
933
1008
|
if (objData.$Parameter[i].$Collection && !paramType.items) {
|
|
934
1009
|
obj[objType].params[objData.$Parameter[i].$Name] = {};
|
|
935
1010
|
obj[objType].params[objData.$Parameter[i].$Name].items = paramType;
|
|
936
|
-
if(objData.$Parameter[i].$Nullable
|
|
1011
|
+
if (!objData.$Parameter[i].$Nullable) {
|
|
937
1012
|
obj[objType].params[objData.$Parameter[i].$Name].items["notNull"] = true;
|
|
938
1013
|
}
|
|
939
1014
|
} else {
|
|
940
1015
|
obj[objType].params[objData.$Parameter[i].$Name] = paramType;
|
|
941
1016
|
if (!paramType.items) {
|
|
942
|
-
if(objData.$Parameter[i].$Nullable
|
|
1017
|
+
if (!objData.$Parameter[i].$Nullable) {
|
|
943
1018
|
obj[objType].params[objData.$Parameter[i].$Name]["notNull"] = true;
|
|
944
1019
|
}
|
|
945
1020
|
}
|
|
946
1021
|
}
|
|
947
1022
|
}
|
|
948
1023
|
} else {
|
|
949
|
-
let message = '"' + objData.$Parameter[i].$Type + '" is not supported (in element:"' + temp + '")';
|
|
950
|
-
console.log(warn(message));
|
|
1024
|
+
// let message = '"' + objData.$Parameter[i].$Type + '" is not supported (in element:"' + temp + '")';
|
|
1025
|
+
// console.log(warn(message));
|
|
1026
|
+
throw new Error(messages.UNRESOLVED_TYPE + `'${objData.$Parameter[i].$Type}' in element: '${temp}'.`);
|
|
951
1027
|
}
|
|
952
1028
|
if (obj[objType].params[objData.$Parameter[i].$Name])
|
|
953
1029
|
Object.assign(obj[objType].params[objData.$Parameter[i].$Name], annotations)
|
|
@@ -961,13 +1037,24 @@ function _parseUnbounded(schemaData, flag, parserContext) {
|
|
|
961
1037
|
if (objData.$ReturnType && Object.keys(objData.$ReturnType).length > 0 && obj) {
|
|
962
1038
|
let returnValue = {};
|
|
963
1039
|
let annotations = {};
|
|
1040
|
+
let hasCdsTypeMapping = false;
|
|
964
1041
|
// check if the return type is pre-defined, undefined or custom defined
|
|
965
|
-
if (edmxncdsdatatype[objData.$ReturnType.$Type] || edmxncdsdatatype[objData.$ReturnType.$Type + "_a"]
|
|
1042
|
+
if (edmxncdsdatatype[objData.$ReturnType.$Type] || edmxncdsdatatype[objData.$ReturnType.$Type + "_a"] ||
|
|
1043
|
+
(!objData.$ReturnType.$Type && objData.$ReturnType.$MaxLength)
|
|
1044
|
+
){
|
|
966
1045
|
returnValue = generatePropertyCsn(objData.$ReturnType, false);
|
|
967
1046
|
} else {
|
|
968
|
-
let type
|
|
1047
|
+
let type;
|
|
1048
|
+
if (extendedPrimitiveTypes.includes(objData.$ReturnType.$Type)) {
|
|
1049
|
+
hasCdsTypeMapping = true;
|
|
1050
|
+
} else {
|
|
1051
|
+
type = _getDatatype(objData.$ReturnType.$Type, parserContext);
|
|
1052
|
+
}
|
|
969
1053
|
_includeExternalNamespaceAnnotation(objData.$ReturnType, annotations);
|
|
970
1054
|
if (type) returnValue["type"] = type;
|
|
1055
|
+
if (!type && !hasCdsTypeMapping) {
|
|
1056
|
+
throw new Error(messages.UNRESOLVED_TYPE + `'${objData.$ReturnType.$Type}'`);
|
|
1057
|
+
}
|
|
971
1058
|
}
|
|
972
1059
|
if (Object.keys(returnValue).length > 0) {
|
|
973
1060
|
if (returnValue.type || returnValue.items.type) {
|
|
@@ -976,25 +1063,34 @@ function _parseUnbounded(schemaData, flag, parserContext) {
|
|
|
976
1063
|
if (objData.$ReturnType.$Collection && !returnValue.items) {
|
|
977
1064
|
obj[objType].returns.items = {};
|
|
978
1065
|
obj[objType].returns.items = returnValue;
|
|
979
|
-
if(objData.$ReturnType.$Nullable
|
|
1066
|
+
if (!objData.$ReturnType.$Nullable) {
|
|
980
1067
|
obj[objType].returns.items["notNull"] = true;
|
|
981
1068
|
}
|
|
982
1069
|
} else {
|
|
983
1070
|
obj[objType].returns = returnValue;
|
|
984
1071
|
if (!returnValue.items) {
|
|
985
|
-
if(objData.$ReturnType.$Nullable
|
|
986
|
-
|
|
987
|
-
|
|
1072
|
+
if (!objData.$ReturnType.$Nullable) {
|
|
1073
|
+
obj[objType].returns["notNull"] = true;
|
|
1074
|
+
}
|
|
988
1075
|
}
|
|
989
1076
|
}
|
|
990
1077
|
}
|
|
991
1078
|
}
|
|
992
1079
|
else {
|
|
993
|
-
|
|
994
|
-
|
|
1080
|
+
obj[objType].returns = {};
|
|
1081
|
+
// check if return type is a collection
|
|
1082
|
+
if ((objData.$ReturnType.$Collection && !returnValue.items)) {
|
|
1083
|
+
obj[objType].returns = { "@odata.Type":objData.$ReturnType.$Type };
|
|
1084
|
+
obj[objType].returns.items = {};
|
|
1085
|
+
obj[objType].returns.items = { "type": "cds.String" };
|
|
1086
|
+
} else
|
|
1087
|
+
obj[objType].returns = { "type": "cds.String", "@odata.Type": objData.$ReturnType.$Type };
|
|
995
1088
|
}
|
|
996
1089
|
if (obj[objType].returns)
|
|
997
1090
|
Object.assign(obj[objType].returns, annotations);
|
|
1091
|
+
} else {
|
|
1092
|
+
if (objData.$Kind === 'Function')
|
|
1093
|
+
throw new Error(messages.NO_RETURN_TYPE + `'${ub}'.`);
|
|
998
1094
|
}
|
|
999
1095
|
}
|
|
1000
1096
|
unboundedObj = Object.assign(unboundedObj, obj);
|
|
@@ -1082,6 +1178,7 @@ function _replaceSpecialCharacters(text) {
|
|
|
1082
1178
|
}
|
|
1083
1179
|
|
|
1084
1180
|
function _checkAnnotatationTerm(annotation, path, no_of_terms, targetString, vocab) {
|
|
1181
|
+
let annoTerm = targetString.substring(targetString.indexOf('@') + 1).split('.')[0];
|
|
1085
1182
|
if (path) {
|
|
1086
1183
|
if (targetString === "@Core.Description" && annotation[1]["@Core.Description"]) {
|
|
1087
1184
|
if (path.doc === undefined)
|
|
@@ -1095,9 +1192,20 @@ function _checkAnnotatationTerm(annotation, path, no_of_terms, targetString, voc
|
|
|
1095
1192
|
else if (targetString === "@Core.OptionalParameter" && annotation[1]["@Core.OptionalParameter"]) {
|
|
1096
1193
|
_captureOptionalParameter(annotation, path);
|
|
1097
1194
|
}
|
|
1098
|
-
else if (vocab) {
|
|
1099
|
-
if (vocab.includes(
|
|
1100
|
-
|
|
1195
|
+
else if (vocab) {
|
|
1196
|
+
if (vocab.includes(annoTerm)) {
|
|
1197
|
+
if (annoTerm === "Capabilities") {
|
|
1198
|
+
path[targetString] = annotation[1][1];
|
|
1199
|
+
}
|
|
1200
|
+
else if (annotation[1][targetString]?.$Cast) {
|
|
1201
|
+
path[targetString] = Number(annotation[1][targetString].$Cast);
|
|
1202
|
+
}
|
|
1203
|
+
else if (annotation[1][targetString]?.$Path) {
|
|
1204
|
+
path[targetString] = { "=": annotation[1][targetString].$Path };
|
|
1205
|
+
}
|
|
1206
|
+
else {
|
|
1207
|
+
path[targetString] = annotation[1][targetString] === null ? true : annotation[1][targetString];
|
|
1208
|
+
}
|
|
1101
1209
|
}
|
|
1102
1210
|
}
|
|
1103
1211
|
}
|
|
@@ -1110,37 +1218,38 @@ function checkEntitySetMap(pathName, parserContext, index = 0) {
|
|
|
1110
1218
|
return pathName;
|
|
1111
1219
|
}
|
|
1112
1220
|
|
|
1113
|
-
function _checkAnnotationTarget(annotation,
|
|
1221
|
+
function _checkAnnotationTarget(annotation, csnDefs, str, no_of_terms, vocab, parserContext) {
|
|
1114
1222
|
if ((annotation[0].indexOf('/') === -1 && annotation[0].indexOf('(') === -1) || annotation[0].includes("Container")) {
|
|
1115
|
-
if (
|
|
1223
|
+
if (csnDefs[annotation[0]]) {
|
|
1116
1224
|
let path = annotation[0].split('/');
|
|
1117
1225
|
let pathFromEntityTypeMap = parserContext.entitySetToEntityTypeMap.get(path[0]);
|
|
1118
1226
|
if (pathFromEntityTypeMap != null) {
|
|
1119
1227
|
if (pathFromEntityTypeMap.length > 1) {
|
|
1120
1228
|
for (let index = 0; index < pathFromEntityTypeMap.length; index++) {
|
|
1121
1229
|
let path1 = checkEntitySetMap(path[0], parserContext, index);
|
|
1122
|
-
_checkAnnotatationTerm(annotation,
|
|
1230
|
+
_checkAnnotatationTerm(annotation, csnDefs[path1], no_of_terms, str, vocab);
|
|
1123
1231
|
}
|
|
1124
1232
|
} else {
|
|
1125
|
-
_checkAnnotatationTerm(annotation,
|
|
1233
|
+
_checkAnnotatationTerm(annotation, csnDefs[annotation[0]], no_of_terms, str, vocab);
|
|
1126
1234
|
}
|
|
1127
1235
|
}
|
|
1128
1236
|
else {
|
|
1129
|
-
_checkAnnotatationTerm(annotation,
|
|
1237
|
+
_checkAnnotatationTerm(annotation, csnDefs[annotation[0]], no_of_terms, str, vocab);
|
|
1130
1238
|
}
|
|
1131
1239
|
}
|
|
1240
|
+
|
|
1132
1241
|
if (annotation[0].indexOf('/') > 0) {
|
|
1133
1242
|
let path = annotation[0].split('/');
|
|
1134
1243
|
let temp = parserContext.namespace + '.' + path[1];
|
|
1135
1244
|
let path1 = checkEntitySetMap(temp, parserContext);
|
|
1136
|
-
if (
|
|
1137
|
-
_checkAnnotatationTerm(annotation,
|
|
1245
|
+
if (csnDefs[path1]) {
|
|
1246
|
+
_checkAnnotatationTerm(annotation, csnDefs[path1], no_of_terms, str, vocab);
|
|
1138
1247
|
}
|
|
1139
1248
|
}
|
|
1140
1249
|
else if (annotation[0].includes("Container")) {
|
|
1141
1250
|
let path = annotation[0].substring(0, annotation[0].lastIndexOf('.'));
|
|
1142
1251
|
let actualPath = checkEntitySetMap(path, parserContext);
|
|
1143
|
-
_checkAnnotatationTerm(annotation,
|
|
1252
|
+
_checkAnnotatationTerm(annotation, csnDefs[actualPath], no_of_terms, str, vocab);
|
|
1144
1253
|
}
|
|
1145
1254
|
else if (annotation[0].indexOf('(') === -1 && (annotation[0].indexOf('/') === -1)) {
|
|
1146
1255
|
let path = annotation[0].split('/');
|
|
@@ -1149,7 +1258,7 @@ function _checkAnnotationTarget(annotation, cdsDefs, str, no_of_terms, vocab, pa
|
|
|
1149
1258
|
if (pathFromEntityTypeMap.length > 1) {
|
|
1150
1259
|
for (let index = 0; index < pathFromEntityTypeMap.length; index++) {
|
|
1151
1260
|
let path1 = checkEntitySetMap(path[0], parserContext, index);
|
|
1152
|
-
_checkAnnotatationTerm(annotation,
|
|
1261
|
+
_checkAnnotatationTerm(annotation, csnDefs[path1], no_of_terms, str, vocab);
|
|
1153
1262
|
}
|
|
1154
1263
|
}
|
|
1155
1264
|
}
|
|
@@ -1162,39 +1271,39 @@ function _checkAnnotationTarget(annotation, cdsDefs, str, no_of_terms, vocab, pa
|
|
|
1162
1271
|
if (pathFromEntityTypeMap.length > 1) {
|
|
1163
1272
|
for (let index = 0; index < pathFromEntityTypeMap.length; index++) {
|
|
1164
1273
|
let path1 = checkEntitySetMap(path[0], parserContext, index);
|
|
1165
|
-
_checkAnnotatationTerm(annotation,
|
|
1274
|
+
_checkAnnotatationTerm(annotation, csnDefs[path1]["elements"][path[1]], no_of_terms, str, vocab);
|
|
1166
1275
|
}
|
|
1167
1276
|
}
|
|
1168
1277
|
else {
|
|
1169
1278
|
let path1 = checkEntitySetMap(path[0], parserContext);
|
|
1170
|
-
if (
|
|
1171
|
-
_checkAnnotatationTerm(annotation,
|
|
1279
|
+
if (csnDefs[path1]) {
|
|
1280
|
+
_checkAnnotatationTerm(annotation, csnDefs[path1]["elements"][path[1]], no_of_terms, str, vocab);
|
|
1172
1281
|
}
|
|
1173
1282
|
}
|
|
1174
1283
|
}
|
|
1175
1284
|
else {
|
|
1176
|
-
if (
|
|
1177
|
-
_checkAnnotatationTerm(annotation,
|
|
1285
|
+
if (csnDefs[path[0]]) {
|
|
1286
|
+
_checkAnnotatationTerm(annotation, csnDefs[path[0]]["elements"][path[1]], no_of_terms, str, vocab);
|
|
1178
1287
|
}
|
|
1179
1288
|
}
|
|
1180
1289
|
}
|
|
1181
1290
|
else {
|
|
1182
1291
|
let path = annotation[0].split('(');
|
|
1183
1292
|
let actualPath = checkEntitySetMap(path[0], parserContext);
|
|
1184
|
-
if (
|
|
1293
|
+
if (csnDefs[actualPath] === undefined) {
|
|
1185
1294
|
let temp = path[1].split(')');
|
|
1186
1295
|
let path1 = temp[0].split(',');
|
|
1187
1296
|
let path2 = path[0].split('.');
|
|
1188
|
-
if (
|
|
1189
|
-
_checkAnnotatationTerm(annotation,
|
|
1297
|
+
if (csnDefs[path1[0]]) {
|
|
1298
|
+
_checkAnnotatationTerm(annotation, csnDefs[path1[0]]["actions"][path2[1]], no_of_terms, str, vocab);
|
|
1190
1299
|
}
|
|
1191
1300
|
} else {
|
|
1192
1301
|
if (path[1].indexOf('/') === -1) {
|
|
1193
|
-
_checkAnnotatationTerm(annotation,
|
|
1302
|
+
_checkAnnotatationTerm(annotation, csnDefs[path[0]], no_of_terms, str, vocab);
|
|
1194
1303
|
} else {
|
|
1195
1304
|
let path1 = path[1].split('/');
|
|
1196
|
-
if (
|
|
1197
|
-
_checkAnnotatationTerm(annotation,
|
|
1305
|
+
if (csnDefs[path[0]] && csnDefs[path[0]]["params"]) {
|
|
1306
|
+
_checkAnnotatationTerm(annotation, csnDefs[path[0]]["params"][path1[1]], no_of_terms, str, vocab);
|
|
1198
1307
|
}
|
|
1199
1308
|
}
|
|
1200
1309
|
}
|
|
@@ -1213,7 +1322,7 @@ function _replaceSchemaDataAnnotation(vocabAlias, vocabNamespce, schemaDataAnnot
|
|
|
1213
1322
|
return JSON.parse(schemaDataAnnotation);
|
|
1214
1323
|
}
|
|
1215
1324
|
|
|
1216
|
-
function _generateDocumentation(edmxAsJson, schemaData,
|
|
1325
|
+
function _generateDocumentation(edmxAsJson, schemaData, csnDefs, parserContext) {
|
|
1217
1326
|
let vocabAlias = [];
|
|
1218
1327
|
let vocab = [];
|
|
1219
1328
|
let vocabNamespce = [];
|
|
@@ -1234,18 +1343,23 @@ function _generateDocumentation(edmxAsJson, schemaData, cdsDefs, parserContext)
|
|
|
1234
1343
|
Object.entries(schemaData[0].$Annotations).map(annotation => {
|
|
1235
1344
|
let no_of_terms;
|
|
1236
1345
|
Object.entries(annotation[1]).forEach(anno => {
|
|
1237
|
-
|
|
1346
|
+
let annoTerm = anno[0].substring(anno[0].indexOf('@') + 1).split('.')[0];
|
|
1347
|
+
|
|
1348
|
+
if (vocab.includes(annoTerm) && annoTerm !== 'Capabilities') {
|
|
1238
1349
|
if (annotation[1].hasOwnProperty('@Core.Description')) {
|
|
1239
1350
|
no_of_terms = true;
|
|
1240
1351
|
}
|
|
1241
1352
|
if (annotation[1].hasOwnProperty('@Common.FieldControl') && controlFieldFlag === 0) {
|
|
1242
|
-
annotation[1]["@Common.FieldControl"] = { "#": annotation[1]["@Common.FieldControl"]}
|
|
1353
|
+
annotation[1]["@Common.FieldControl"] = { "#": annotation[1]["@Common.FieldControl"] };
|
|
1243
1354
|
controlFieldFlag = 1;
|
|
1244
1355
|
}
|
|
1245
1356
|
if (annotation[1].hasOwnProperty('@Common.IsUpperCase')) {
|
|
1246
1357
|
annotation[1]["@Common.IsUpperCase"] = true;
|
|
1247
1358
|
}
|
|
1248
|
-
_checkAnnotationTarget(annotation,
|
|
1359
|
+
_checkAnnotationTarget(annotation, csnDefs, anno[0], no_of_terms, vocab, parserContext);
|
|
1360
|
+
}
|
|
1361
|
+
if (vocab.includes(annoTerm) && annoTerm === 'Capabilities') {
|
|
1362
|
+
_parseCapabilitiesAnnotation(annotation[0], anno, csnDefs, vocab, parserContext);
|
|
1249
1363
|
}
|
|
1250
1364
|
});
|
|
1251
1365
|
controlFieldFlag = 0;
|
|
@@ -1253,6 +1367,72 @@ function _generateDocumentation(edmxAsJson, schemaData, cdsDefs, parserContext)
|
|
|
1253
1367
|
}
|
|
1254
1368
|
}
|
|
1255
1369
|
|
|
1370
|
+
function _flattenAnnotationObject(annotationPrefix, annotationObject) {
|
|
1371
|
+
let flattenedResult = [];
|
|
1372
|
+
|
|
1373
|
+
Object.entries(annotationObject).forEach(annotation => {
|
|
1374
|
+
let currentResult = [];
|
|
1375
|
+
currentResult[0] = annotationPrefix + '.' + annotation[0];
|
|
1376
|
+
currentResult[1] = annotation[1];
|
|
1377
|
+
flattenedResult.push(currentResult);
|
|
1378
|
+
});
|
|
1379
|
+
|
|
1380
|
+
return flattenedResult;
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
function _removeTypeInAnnotation(annotationObject) {
|
|
1384
|
+
Object.keys(annotationObject).forEach(key => {
|
|
1385
|
+
if (key === "$Type") delete annotationObject[key];
|
|
1386
|
+
else if (annotationObject[key] instanceof Object) {
|
|
1387
|
+
_removeTypeInAnnotation(annotationObject[key]);
|
|
1388
|
+
}
|
|
1389
|
+
});
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
function _parseCapabilitiesAnnotation(annotationTargetPath, currentAnnotation, csnDefs, vocab, parserContext) {
|
|
1393
|
+
let annotationResult = [annotationTargetPath, ''], currentResult = [], targetString;
|
|
1394
|
+
|
|
1395
|
+
_removeTypeInAnnotation(currentAnnotation);
|
|
1396
|
+
|
|
1397
|
+
/**
|
|
1398
|
+
* For entries like:
|
|
1399
|
+
* <Annotation Term="Capabilities.FilterFunctions"> <Collection> <String>eq</String> <String>ne</String> </Collection> </Annotation>
|
|
1400
|
+
* <Annotation Term="Capabilities.DeleteRestrictions.Deletable" Bool="true"/>
|
|
1401
|
+
*
|
|
1402
|
+
* simply preserve the value as it is
|
|
1403
|
+
*/
|
|
1404
|
+
if (currentAnnotation[1] instanceof Array || !(currentAnnotation[1] instanceof Object)) {
|
|
1405
|
+
targetString = currentAnnotation[0];
|
|
1406
|
+
currentResult = [targetString, currentAnnotation[1]];
|
|
1407
|
+
annotationResult[1] = currentResult;
|
|
1408
|
+
_checkAnnotationTarget(annotationResult, csnDefs, targetString, undefined, vocab, parserContext);
|
|
1409
|
+
}
|
|
1410
|
+
else {
|
|
1411
|
+
Object.keys(currentAnnotation[1]).forEach(annoKey => {
|
|
1412
|
+
let currentAnnoValue = currentAnnotation[1][annoKey];
|
|
1413
|
+
// if the currentAnnoValue is an Object, we need to flatten it
|
|
1414
|
+
if (currentAnnoValue instanceof Object && !(currentAnnoValue instanceof Array)) {
|
|
1415
|
+
targetString = currentAnnotation[0] + '.' + annoKey;
|
|
1416
|
+
let currentResultList = _flattenAnnotationObject(targetString, currentAnnoValue);
|
|
1417
|
+
|
|
1418
|
+
for (let idx = 0; idx < currentResultList.length; idx++) {
|
|
1419
|
+
targetString = currentResultList[idx][0];
|
|
1420
|
+
annotationResult[1] = currentResultList[idx];
|
|
1421
|
+
_checkAnnotationTarget(annotationResult, csnDefs, targetString, undefined, vocab, parserContext);
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
// if the currentAnnoValue is a list or direct value, we preserve as it is
|
|
1425
|
+
else {
|
|
1426
|
+
targetString = currentAnnotation[0] + '.' + annoKey;
|
|
1427
|
+
currentResult[0] = targetString;
|
|
1428
|
+
currentResult[1] = currentAnnoValue;
|
|
1429
|
+
annotationResult[1] = currentResult;
|
|
1430
|
+
_checkAnnotationTarget(annotationResult, csnDefs, targetString, undefined, vocab, parserContext);
|
|
1431
|
+
}
|
|
1432
|
+
});
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1256
1436
|
function _generateLongDescription(annotation, path, no_of_terms) {
|
|
1257
1437
|
if (path) {
|
|
1258
1438
|
path.doc = no_of_terms ? (path.doc += "\n\n") : (path.doc ? (path.doc += "") : (path.doc = ""));
|