@odata2ts/odata2ts 0.29.1 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/README.md +81 -81
- package/lib/FactoryFunctionModel.d.ts +1 -1
- package/lib/FactoryFunctionModel.js.map +1 -1
- package/lib/OptionModel.d.ts +54 -4
- package/lib/OptionModel.js.map +1 -1
- package/lib/app.js +1 -8
- package/lib/app.js.map +1 -1
- package/lib/data-model/DataModel.d.ts +48 -37
- package/lib/data-model/DataModel.js +130 -61
- package/lib/data-model/DataModel.js.map +1 -1
- package/lib/data-model/DataModelDigestion.d.ts +2 -3
- package/lib/data-model/DataModelDigestion.js +74 -96
- package/lib/data-model/DataModelDigestion.js.map +1 -1
- package/lib/data-model/DataModelDigestionV2.d.ts +1 -1
- package/lib/data-model/DataModelDigestionV2.js +30 -15
- package/lib/data-model/DataModelDigestionV2.js.map +1 -1
- package/lib/data-model/DataModelDigestionV4.js +65 -43
- package/lib/data-model/DataModelDigestionV4.js.map +1 -1
- package/lib/data-model/DataTypeModel.d.ts +10 -1
- package/lib/data-model/DataTypeModel.js.map +1 -1
- package/lib/data-model/NamingHelper.d.ts +6 -6
- package/lib/data-model/NamingHelper.js +14 -7
- package/lib/data-model/NamingHelper.js.map +1 -1
- package/lib/data-model/ServiceConfigHelper.d.ts +12 -3
- package/lib/data-model/ServiceConfigHelper.js +73 -11
- package/lib/data-model/ServiceConfigHelper.js.map +1 -1
- package/lib/defaultConfig.js +1 -0
- package/lib/defaultConfig.js.map +1 -1
- package/lib/generator/ImportContainer.d.ts +0 -1
- package/lib/generator/ImportContainer.js +2 -17
- package/lib/generator/ImportContainer.js.map +1 -1
- package/lib/generator/ModelGenerator.js +9 -6
- package/lib/generator/ModelGenerator.js.map +1 -1
- package/lib/generator/QueryObjectGenerator.js +12 -6
- package/lib/generator/QueryObjectGenerator.js.map +1 -1
- package/lib/generator/ServiceGenerator.js +19 -27
- package/lib/generator/ServiceGenerator.js.map +1 -1
- package/lib/project/ProjectManager.d.ts +0 -5
- package/lib/project/ProjectManager.js +1 -21
- package/lib/project/ProjectManager.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,19 +1,43 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DataModel = void 0;
|
|
3
|
+
exports.DataModel = exports.withNamespace = void 0;
|
|
4
4
|
const DataTypeModel_1 = require("./DataTypeModel");
|
|
5
|
-
|
|
5
|
+
function withNamespace(ns, name) {
|
|
6
|
+
// this supports the edge case of an empty string as namespace which isn't really valid according to spec (see CSDL)
|
|
7
|
+
return ns ? `${ns}.${name}` : name;
|
|
8
|
+
}
|
|
9
|
+
exports.withNamespace = withNamespace;
|
|
6
10
|
class DataModel {
|
|
7
|
-
constructor(version, converters = new Map()) {
|
|
11
|
+
constructor(namespaces, version, converters = new Map()) {
|
|
8
12
|
this.version = version;
|
|
9
|
-
this.
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
this.
|
|
13
|
+
this.models = new Map();
|
|
14
|
+
/**
|
|
15
|
+
* Stores unbound operations by their fully qualified name.
|
|
16
|
+
* @private
|
|
17
|
+
*/
|
|
18
|
+
this.unboundOperationTypes = new Map();
|
|
19
|
+
/**
|
|
20
|
+
* Stores operations bound to an entity type by the fully qualified name of the binding entity, e.g.
|
|
21
|
+
* "Trippin.Person".
|
|
22
|
+
* @private
|
|
23
|
+
*/
|
|
24
|
+
this.entityBoundOperationTypes = new Map();
|
|
25
|
+
/**
|
|
26
|
+
* Stores operations bound to an entity collection by the fully qualified name of the binding entity, e.g.
|
|
27
|
+
* "Trippin.Person".
|
|
28
|
+
* @private
|
|
29
|
+
*/
|
|
30
|
+
this.entityCollectionBoundOperationTypes = new Map();
|
|
31
|
+
this.typeDefinitions = new Map();
|
|
32
|
+
this.aliases = {};
|
|
15
33
|
this.container = { entitySets: {}, singletons: {}, functions: {}, actions: {} };
|
|
16
34
|
this.converters = converters;
|
|
35
|
+
this.namespace2Alias = namespaces.reduce((col, [ns, alias]) => {
|
|
36
|
+
if (alias) {
|
|
37
|
+
col[ns] = alias;
|
|
38
|
+
}
|
|
39
|
+
return col;
|
|
40
|
+
}, {});
|
|
17
41
|
}
|
|
18
42
|
/**
|
|
19
43
|
* OData version: 2.0 or 4.0.
|
|
@@ -28,51 +52,62 @@ class DataModel {
|
|
|
28
52
|
isV4() {
|
|
29
53
|
return this.version === DataTypeModel_1.ODataVersion.V4;
|
|
30
54
|
}
|
|
31
|
-
|
|
32
|
-
this.
|
|
55
|
+
retrieveType(fqName, haystack) {
|
|
56
|
+
return haystack.get(fqName) || (this.aliases[fqName] ? haystack.get(this.aliases[fqName]) : undefined);
|
|
57
|
+
}
|
|
58
|
+
addAlias(namespace, name) {
|
|
59
|
+
const alias = this.namespace2Alias[namespace];
|
|
60
|
+
if (alias) {
|
|
61
|
+
this.aliases[withNamespace(alias, name)] = withNamespace(namespace, name);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
addTypeDefinition(namespace, name, type) {
|
|
65
|
+
const fqName = withNamespace(namespace, name);
|
|
66
|
+
this.typeDefinitions.set(fqName, type);
|
|
67
|
+
this.addAlias(namespace, name);
|
|
68
|
+
}
|
|
69
|
+
getPrimitiveType(fqName) {
|
|
70
|
+
return this.retrieveType(fqName, this.typeDefinitions);
|
|
33
71
|
}
|
|
34
|
-
|
|
35
|
-
return this.
|
|
72
|
+
getModel(fqName) {
|
|
73
|
+
return this.retrieveType(fqName, this.models);
|
|
36
74
|
}
|
|
37
|
-
|
|
38
|
-
|
|
75
|
+
addEntityType(namespace, name, model) {
|
|
76
|
+
const fqName = withNamespace(namespace, name);
|
|
77
|
+
this.models.set(fqName, Object.assign(Object.assign({}, model), { dataType: "ModelType" /* DataTypes.ModelType */ }));
|
|
78
|
+
this.addAlias(namespace, name);
|
|
39
79
|
}
|
|
40
80
|
/**
|
|
41
|
-
* Get a specific model by its name.
|
|
81
|
+
* Get a specific model by its fully qualified name.
|
|
42
82
|
*
|
|
43
|
-
* @param
|
|
83
|
+
* @param fqName the fully qualified name of the entity
|
|
44
84
|
* @returns the model type
|
|
45
85
|
*/
|
|
46
|
-
|
|
47
|
-
return this.
|
|
86
|
+
getEntityType(fqName) {
|
|
87
|
+
return this.retrieveType(fqName, this.models);
|
|
48
88
|
}
|
|
49
89
|
/**
|
|
50
90
|
* Retrieve all known EntityType models from the EDMX model.
|
|
51
91
|
*
|
|
52
92
|
* @returns list of model types
|
|
53
93
|
*/
|
|
54
|
-
|
|
55
|
-
|
|
94
|
+
getEntityTypes() {
|
|
95
|
+
const ets = [...this.models.values()].filter((m) => m.dataType === "ModelType" /* DataTypes.ModelType */);
|
|
96
|
+
return this.sortModelsByInheritance(ets);
|
|
56
97
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
*/
|
|
62
|
-
setModels(models) {
|
|
63
|
-
this.modelTypes = models;
|
|
64
|
-
}
|
|
65
|
-
addComplexType(name, model) {
|
|
66
|
-
this.complexTypes[name] = model;
|
|
98
|
+
addComplexType(namespace, name, model) {
|
|
99
|
+
const fqName = withNamespace(namespace, name);
|
|
100
|
+
this.models.set(fqName, Object.assign(Object.assign({}, model), { dataType: "ComplexType" /* DataTypes.ComplexType */ }));
|
|
101
|
+
this.addAlias(namespace, name);
|
|
67
102
|
}
|
|
68
103
|
/**
|
|
69
|
-
* Get a specific model by its name.
|
|
104
|
+
* Get a specific model by its fully qualified name.
|
|
70
105
|
*
|
|
71
|
-
* @param
|
|
106
|
+
* @param fqName the final model name that is generated
|
|
72
107
|
* @returns the model type
|
|
73
108
|
*/
|
|
74
|
-
getComplexType(
|
|
75
|
-
return this.
|
|
109
|
+
getComplexType(fqName) {
|
|
110
|
+
return this.retrieveType(fqName, this.models);
|
|
76
111
|
}
|
|
77
112
|
/**
|
|
78
113
|
* Retrieve all known ComplexType models from the EDMX model.
|
|
@@ -80,44 +115,49 @@ class DataModel {
|
|
|
80
115
|
* @returns list of model types
|
|
81
116
|
*/
|
|
82
117
|
getComplexTypes() {
|
|
83
|
-
|
|
118
|
+
const types = [...this.models.values()].filter((m) => m.dataType === "ComplexType" /* DataTypes.ComplexType */);
|
|
119
|
+
return this.sortModelsByInheritance(types);
|
|
84
120
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
*/
|
|
90
|
-
setComplexTypes(complexTypes) {
|
|
91
|
-
this.complexTypes = complexTypes;
|
|
92
|
-
}
|
|
93
|
-
addEnum(name, type) {
|
|
94
|
-
this.enumTypes[name] = type;
|
|
121
|
+
addEnum(namespace, name, type) {
|
|
122
|
+
const fqName = withNamespace(namespace, name);
|
|
123
|
+
this.models.set(fqName, Object.assign(Object.assign({}, type), { dataType: "EnumType" /* DataTypes.EnumType */ }));
|
|
124
|
+
this.addAlias(namespace, name);
|
|
95
125
|
}
|
|
96
126
|
/**
|
|
97
127
|
* Get list of all known enums, i.e. EnumType nodes from the EDMX model.
|
|
98
128
|
* @returns list of enum types
|
|
99
129
|
*/
|
|
100
130
|
getEnums() {
|
|
101
|
-
return
|
|
131
|
+
return [...this.models.values()].filter((m) => m.dataType === "EnumType" /* DataTypes.EnumType */);
|
|
102
132
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
this.operationTypes[binding].push(operationType);
|
|
133
|
+
addUnboundOperationType(namespace, operationType) {
|
|
134
|
+
this.unboundOperationTypes.set(operationType.fqName, operationType);
|
|
135
|
+
this.addAlias(namespace, operationType.odataName);
|
|
108
136
|
}
|
|
109
137
|
getUnboundOperationTypes() {
|
|
110
|
-
|
|
111
|
-
|
|
138
|
+
return [...this.unboundOperationTypes.values()];
|
|
139
|
+
}
|
|
140
|
+
getUnboundOperationType(fqOpName) {
|
|
141
|
+
return this.retrieveType(fqOpName, this.unboundOperationTypes);
|
|
142
|
+
}
|
|
143
|
+
addBoundOperationType(namespace, bindingProp, operationType) {
|
|
144
|
+
const fqEntityType = bindingProp.fqType;
|
|
145
|
+
const store = bindingProp.isCollection ? this.entityCollectionBoundOperationTypes : this.entityBoundOperationTypes;
|
|
146
|
+
const list = store.get(fqEntityType);
|
|
147
|
+
if (list) {
|
|
148
|
+
list.push(operationType);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
store.set(fqEntityType, [operationType]);
|
|
152
|
+
}
|
|
112
153
|
}
|
|
113
|
-
|
|
114
|
-
const operations = this.
|
|
115
|
-
return
|
|
154
|
+
getEntityTypeOperations(fqEntityName) {
|
|
155
|
+
const operations = this.retrieveType(fqEntityName, this.entityBoundOperationTypes);
|
|
156
|
+
return operations || [];
|
|
116
157
|
}
|
|
117
|
-
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
return [...collOps, ...entityOps];
|
|
158
|
+
getEntitySetOperations(fqEntityName) {
|
|
159
|
+
const operations = this.retrieveType(fqEntityName, this.entityCollectionBoundOperationTypes);
|
|
160
|
+
return operations || [];
|
|
121
161
|
}
|
|
122
162
|
addAction(name, action) {
|
|
123
163
|
this.container.actions[name] = action;
|
|
@@ -137,6 +177,35 @@ class DataModel {
|
|
|
137
177
|
getConverter(dataType) {
|
|
138
178
|
return this.converters.get(dataType);
|
|
139
179
|
}
|
|
180
|
+
sortModelsByInheritance(models) {
|
|
181
|
+
// recursively visit all models and sort them by inheritance such that base classes
|
|
182
|
+
// are always before derived classes
|
|
183
|
+
const sorted = [];
|
|
184
|
+
const visitedModels = new Set();
|
|
185
|
+
const inProgressModels = new Set();
|
|
186
|
+
function visit(model) {
|
|
187
|
+
const fqName = model.fqName;
|
|
188
|
+
if (inProgressModels.has(fqName)) {
|
|
189
|
+
throw new Error(`Cyclic inheritance detected for model "${fqName}"!`);
|
|
190
|
+
}
|
|
191
|
+
if (!visitedModels.has(fqName)) {
|
|
192
|
+
inProgressModels.add(fqName);
|
|
193
|
+
for (const baseClassName of model.baseClasses) {
|
|
194
|
+
const baseClass = models.find((e) => e.fqName === baseClassName);
|
|
195
|
+
if (baseClass) {
|
|
196
|
+
visit(baseClass);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
visitedModels.add(fqName);
|
|
200
|
+
inProgressModels.delete(fqName);
|
|
201
|
+
sorted.push(model);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
for (const model of models) {
|
|
205
|
+
visit(model);
|
|
206
|
+
}
|
|
207
|
+
return sorted;
|
|
208
|
+
}
|
|
140
209
|
}
|
|
141
210
|
exports.DataModel = DataModel;
|
|
142
211
|
//# sourceMappingURL=DataModel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataModel.js","sourceRoot":"","sources":["../../src/data-model/DataModel.ts"],"names":[],"mappings":"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","sourcesContent":["import { MappedConverterChains } from \"@odata2ts/converter-runtime\";\r\nimport { ODataTypesV2, ODataTypesV4 } from \"@odata2ts/odata-core\";\r\n\r\nimport {\r\n ActionImportType,\r\n ComplexType,\r\n EntityContainerModel,\r\n EntitySetType,\r\n EnumType,\r\n FunctionImportType,\r\n ModelType,\r\n ODataVersion,\r\n OperationType,\r\n SingletonType,\r\n} from \"./DataTypeModel\";\r\n\r\nexport interface ProjectFiles {\r\n model: string;\r\n qObject: string;\r\n service: string;\r\n}\r\n\r\nconst ROOT_OPERATION_BINDING = \"/\";\r\n\r\nexport class DataModel {\r\n private readonly converters: MappedConverterChains;\r\n\r\n private modelTypes: { [name: string]: ModelType } = {};\r\n private complexTypes: { [name: string]: ComplexType } = {};\r\n private enumTypes: { [name: string]: EnumType } = {};\r\n // combines functions & actions\r\n private operationTypes: { [binding: string]: Array<OperationType> } = {};\r\n private typeDefinitions: { [name: string]: string } = {};\r\n private container: EntityContainerModel = { entitySets: {}, singletons: {}, functions: {}, actions: {} };\r\n\r\n constructor(private version: ODataVersion, converters: MappedConverterChains = new Map()) {\r\n this.converters = converters;\r\n }\r\n\r\n /**\r\n * OData version: 2.0 or 4.0.\r\n * @returns\r\n */\r\n public getODataVersion() {\r\n return this.version;\r\n }\r\n\r\n public isV2() {\r\n return this.version === ODataVersion.V2;\r\n }\r\n\r\n public isV4() {\r\n return this.version === ODataVersion.V4;\r\n }\r\n\r\n public addTypeDefinition(name: string, type: string) {\r\n this.typeDefinitions[name] = type;\r\n }\r\n\r\n public getPrimitiveType(name: string): string | undefined {\r\n return this.typeDefinitions[name];\r\n }\r\n\r\n public addModel(name: string, model: ModelType) {\r\n this.modelTypes[name] = model;\r\n }\r\n\r\n /**\r\n * Get a specific model by its name.\r\n *\r\n * @param modelName the final model name that is generated\r\n * @returns the model type\r\n */\r\n public getModel(modelName: string) {\r\n return this.modelTypes[modelName];\r\n }\r\n\r\n /**\r\n * Retrieve all known EntityType models from the EDMX model.\r\n *\r\n * @returns list of model types\r\n */\r\n public getModels() {\r\n return Object.values(this.modelTypes);\r\n }\r\n\r\n /**\r\n * Set all model entity types\r\n *\r\n * @param models new model types\r\n */\r\n public setModels(models: { [name: string]: ModelType }) {\r\n this.modelTypes = models;\r\n }\r\n\r\n public addComplexType(name: string, model: ComplexType) {\r\n this.complexTypes[name] = model;\r\n }\r\n\r\n /**\r\n * Get a specific model by its name.\r\n *\r\n * @param name the final model name that is generated\r\n * @returns the model type\r\n */\r\n public getComplexType(name: string) {\r\n return this.complexTypes[name];\r\n }\r\n\r\n /**\r\n * Retrieve all known ComplexType models from the EDMX model.\r\n *\r\n * @returns list of model types\r\n */\r\n public getComplexTypes() {\r\n return Object.values(this.complexTypes);\r\n }\r\n\r\n /**\r\n * Set all complex types\r\n *\r\n * @param models new complex types\r\n */\r\n public setComplexTypes(complexTypes: { [name: string]: ComplexType }) {\r\n this.complexTypes = complexTypes;\r\n }\r\n\r\n public addEnum(name: string, type: EnumType) {\r\n this.enumTypes[name] = type;\r\n }\r\n\r\n /**\r\n * Get list of all known enums, i.e. EnumType nodes from the EDMX model.\r\n * @returns list of enum types\r\n */\r\n public getEnums() {\r\n return Object.values(this.enumTypes);\r\n }\r\n\r\n public addOperationType(binding: string, operationType: OperationType) {\r\n if (!this.operationTypes[binding]) {\r\n this.operationTypes[binding] = [];\r\n }\r\n\r\n this.operationTypes[binding].push(operationType);\r\n }\r\n\r\n public getUnboundOperationTypes(): Array<OperationType> {\r\n const operations = this.operationTypes[ROOT_OPERATION_BINDING];\r\n return !operations ? [] : [...operations];\r\n }\r\n\r\n public getOperationTypeByBinding(binding: string): Array<OperationType> {\r\n const operations = this.operationTypes[binding];\r\n return !operations ? [] : [...operations];\r\n }\r\n\r\n public getOperationTypeByEntityOrCollectionBinding(binding: string): Array<OperationType> {\r\n const entityOps = this.operationTypes[binding] || [];\r\n const collOps = this.operationTypes[`Collection(${binding})`] || [];\r\n return [...collOps, ...entityOps];\r\n }\r\n\r\n public addAction(name: string, action: ActionImportType) {\r\n this.container.actions[name] = action;\r\n }\r\n\r\n public addFunction(name: string, func: FunctionImportType) {\r\n this.container.functions[name] = func;\r\n }\r\n\r\n public addSingleton(name: string, singleton: SingletonType) {\r\n this.container.singletons[name] = singleton;\r\n }\r\n\r\n public addEntitySet(name: string, entitySet: EntitySetType) {\r\n this.container.entitySets[name] = entitySet;\r\n }\r\n\r\n public getEntityContainer() {\r\n return this.container;\r\n }\r\n\r\n public getConverter(dataType: ODataTypesV2 | ODataTypesV4 | string) {\r\n return this.converters.get(dataType);\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"DataModel.js","sourceRoot":"","sources":["../../src/data-model/DataModel.ts"],"names":[],"mappings":"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","sourcesContent":["import { MappedConverterChains } from \"@odata2ts/converter-runtime\";\r\nimport { ODataTypesV2, ODataTypesV4 } from \"@odata2ts/odata-core\";\r\n\r\nimport {\r\n ActionImportType,\r\n ComplexType,\r\n DataTypes,\r\n EntityContainerModel,\r\n EntitySetType,\r\n EnumType,\r\n FunctionImportType,\r\n ModelType,\r\n ODataVersion,\r\n OperationType,\r\n PropertyModel,\r\n SingletonType,\r\n} from \"./DataTypeModel\";\r\n\r\nexport interface ProjectFiles {\r\n model: string;\r\n qObject: string;\r\n service: string;\r\n}\r\n\r\n/**\r\n * Each namespace is represented as tuple: 1. the namespace 2. the alias, if any.\r\n */\r\nexport type NamespaceWithAlias = [string, string?];\r\n\r\nexport function withNamespace(ns: string, name: string) {\r\n // this supports the edge case of an empty string as namespace which isn't really valid according to spec (see CSDL)\r\n return ns ? `${ns}.${name}` : name;\r\n}\r\n\r\nexport class DataModel {\r\n private readonly converters: MappedConverterChains;\r\n\r\n private models = new Map<string, ModelType | ComplexType | EnumType>();\r\n /**\r\n * Stores unbound operations by their fully qualified name.\r\n * @private\r\n */\r\n private unboundOperationTypes = new Map<string, OperationType>();\r\n /**\r\n * Stores operations bound to an entity type by the fully qualified name of the binding entity, e.g.\r\n * \"Trippin.Person\".\r\n * @private\r\n */\r\n private entityBoundOperationTypes = new Map<string, Array<OperationType>>();\r\n /**\r\n * Stores operations bound to an entity collection by the fully qualified name of the binding entity, e.g.\r\n * \"Trippin.Person\".\r\n * @private\r\n */\r\n private entityCollectionBoundOperationTypes = new Map<string, Array<OperationType>>();\r\n private readonly namespace2Alias: { [ns: string]: string };\r\n private typeDefinitions = new Map<string, string>();\r\n private aliases: Record<string, string> = {};\r\n private container: EntityContainerModel = { entitySets: {}, singletons: {}, functions: {}, actions: {} };\r\n\r\n constructor(\r\n namespaces: Array<NamespaceWithAlias>,\r\n private version: ODataVersion,\r\n converters: MappedConverterChains = new Map()\r\n ) {\r\n this.converters = converters;\r\n this.namespace2Alias = namespaces.reduce<Record<string, string>>((col, [ns, alias]) => {\r\n if (alias) {\r\n col[ns] = alias;\r\n }\r\n return col;\r\n }, {});\r\n }\r\n\r\n /**\r\n * OData version: 2.0 or 4.0.\r\n * @returns\r\n */\r\n public getODataVersion() {\r\n return this.version;\r\n }\r\n\r\n public isV2() {\r\n return this.version === ODataVersion.V2;\r\n }\r\n\r\n public isV4() {\r\n return this.version === ODataVersion.V4;\r\n }\r\n\r\n private retrieveType<T>(fqName: string, haystack: Map<string, T>): T | undefined {\r\n return haystack.get(fqName) || (this.aliases[fqName] ? haystack.get(this.aliases[fqName]) : undefined);\r\n }\r\n\r\n private addAlias(namespace: string, name: string) {\r\n const alias = this.namespace2Alias[namespace];\r\n if (alias) {\r\n this.aliases[withNamespace(alias, name)] = withNamespace(namespace, name);\r\n }\r\n }\r\n\r\n public addTypeDefinition(namespace: string, name: string, type: string) {\r\n const fqName = withNamespace(namespace, name);\r\n this.typeDefinitions.set(fqName, type);\r\n this.addAlias(namespace, name);\r\n }\r\n\r\n public getPrimitiveType(fqName: string): string | undefined {\r\n return this.retrieveType(fqName, this.typeDefinitions);\r\n }\r\n\r\n public getModel(fqName: string) {\r\n return this.retrieveType(fqName, this.models);\r\n }\r\n\r\n public addEntityType(namespace: string, name: string, model: Omit<ModelType, \"dataType\">) {\r\n const fqName = withNamespace(namespace, name);\r\n this.models.set(fqName, { ...model, dataType: DataTypes.ModelType });\r\n this.addAlias(namespace, name);\r\n }\r\n\r\n /**\r\n * Get a specific model by its fully qualified name.\r\n *\r\n * @param fqName the fully qualified name of the entity\r\n * @returns the model type\r\n */\r\n public getEntityType(fqName: string) {\r\n return this.retrieveType(fqName, this.models) as ModelType;\r\n }\r\n\r\n /**\r\n * Retrieve all known EntityType models from the EDMX model.\r\n *\r\n * @returns list of model types\r\n */\r\n public getEntityTypes() {\r\n const ets = [...this.models.values()].filter((m): m is ModelType => m.dataType === DataTypes.ModelType);\r\n return this.sortModelsByInheritance(ets);\r\n }\r\n\r\n public addComplexType(namespace: string, name: string, model: Omit<ComplexType, \"dataType\">) {\r\n const fqName = withNamespace(namespace, name);\r\n this.models.set(fqName, { ...model, dataType: DataTypes.ComplexType });\r\n this.addAlias(namespace, name);\r\n }\r\n\r\n /**\r\n * Get a specific model by its fully qualified name.\r\n *\r\n * @param fqName the final model name that is generated\r\n * @returns the model type\r\n */\r\n public getComplexType(fqName: string) {\r\n return this.retrieveType(fqName, this.models) as ComplexType;\r\n }\r\n\r\n /**\r\n * Retrieve all known ComplexType models from the EDMX model.\r\n *\r\n * @returns list of model types\r\n */\r\n public getComplexTypes() {\r\n const types = [...this.models.values()].filter((m): m is ComplexType => m.dataType === DataTypes.ComplexType);\r\n return this.sortModelsByInheritance(types);\r\n }\r\n\r\n public addEnum(namespace: string, name: string, type: Omit<EnumType, \"dataType\">) {\r\n const fqName = withNamespace(namespace, name);\r\n this.models.set(fqName, { ...type, dataType: DataTypes.EnumType });\r\n this.addAlias(namespace, name);\r\n }\r\n\r\n /**\r\n * Get list of all known enums, i.e. EnumType nodes from the EDMX model.\r\n * @returns list of enum types\r\n */\r\n public getEnums() {\r\n return [...this.models.values()].filter((m): m is EnumType => m.dataType === DataTypes.EnumType);\r\n }\r\n\r\n public addUnboundOperationType(namespace: string, operationType: OperationType) {\r\n this.unboundOperationTypes.set(operationType.fqName, operationType);\r\n this.addAlias(namespace, operationType.odataName);\r\n }\r\n\r\n public getUnboundOperationTypes(): Array<OperationType> {\r\n return [...this.unboundOperationTypes.values()];\r\n }\r\n\r\n public getUnboundOperationType(fqOpName: string): OperationType | undefined {\r\n return this.retrieveType(fqOpName, this.unboundOperationTypes);\r\n }\r\n\r\n public addBoundOperationType(namespace: string, bindingProp: PropertyModel, operationType: OperationType) {\r\n const fqEntityType = bindingProp.fqType;\r\n\r\n const store = bindingProp.isCollection ? this.entityCollectionBoundOperationTypes : this.entityBoundOperationTypes;\r\n const list = store.get(fqEntityType);\r\n if (list) {\r\n list.push(operationType);\r\n } else {\r\n store.set(fqEntityType, [operationType]);\r\n }\r\n }\r\n\r\n public getEntityTypeOperations(fqEntityName: string): Array<OperationType> {\r\n const operations = this.retrieveType(fqEntityName, this.entityBoundOperationTypes);\r\n return operations || [];\r\n }\r\n\r\n public getEntitySetOperations(fqEntityName: string): Array<OperationType> {\r\n const operations = this.retrieveType(fqEntityName, this.entityCollectionBoundOperationTypes);\r\n return operations || [];\r\n }\r\n\r\n public addAction(name: string, action: ActionImportType) {\r\n this.container.actions[name] = action;\r\n }\r\n\r\n public addFunction(name: string, func: FunctionImportType) {\r\n this.container.functions[name] = func;\r\n }\r\n\r\n public addSingleton(name: string, singleton: SingletonType) {\r\n this.container.singletons[name] = singleton;\r\n }\r\n\r\n public addEntitySet(name: string, entitySet: EntitySetType) {\r\n this.container.entitySets[name] = entitySet;\r\n }\r\n\r\n public getEntityContainer() {\r\n return this.container;\r\n }\r\n\r\n public getConverter(dataType: ODataTypesV2 | ODataTypesV4 | string) {\r\n return this.converters.get(dataType);\r\n }\r\n\r\n private sortModelsByInheritance<Type extends Omit<ComplexType, \"dataType\">>(models: Array<Type>): Array<Type> {\r\n // recursively visit all models and sort them by inheritance such that base classes\r\n // are always before derived classes\r\n const sorted: Array<Type> = [];\r\n const visitedModels = new Set<string>();\r\n const inProgressModels = new Set<string>();\r\n\r\n function visit(model: Type) {\r\n const fqName = model.fqName;\r\n if (inProgressModels.has(fqName)) {\r\n throw new Error(`Cyclic inheritance detected for model \"${fqName}\"!`);\r\n }\r\n\r\n if (!visitedModels.has(fqName)) {\r\n inProgressModels.add(fqName);\r\n\r\n for (const baseClassName of model.baseClasses) {\r\n const baseClass = models.find((e) => e.fqName === baseClassName);\r\n if (baseClass) {\r\n visit(baseClass);\r\n }\r\n }\r\n visitedModels.add(fqName);\r\n inProgressModels.delete(fqName);\r\n sorted.push(model);\r\n }\r\n }\r\n\r\n for (const model of models) {\r\n visit(model);\r\n }\r\n return sorted;\r\n }\r\n}\r\n"]}
|
|
@@ -20,11 +20,12 @@ export declare abstract class Digester<S extends Schema<ET, CT>, ET extends Enti
|
|
|
20
20
|
protected options: DigestionOptions;
|
|
21
21
|
protected namingHelper: NamingHelper;
|
|
22
22
|
protected static EDM_PREFIX: string;
|
|
23
|
-
protected static ROOT_OPERATION: string;
|
|
24
23
|
protected readonly dataModel: DataModel;
|
|
25
24
|
protected readonly serviceConfigHelper: ServiceConfigHelper;
|
|
26
25
|
private model2Type;
|
|
27
26
|
protected constructor(version: ODataVersion, schemas: Array<S>, options: DigestionOptions, namingHelper: NamingHelper, converters?: MappedConverterChains);
|
|
27
|
+
private collectModelTypes;
|
|
28
|
+
private addModel2Type;
|
|
28
29
|
protected abstract getNavigationProps(entityType: ET | ComplexType): Array<Property>;
|
|
29
30
|
protected abstract digestOperations(schema: SchemaV3 | SchemaV4): void;
|
|
30
31
|
protected abstract digestEntityContainer(schema: SchemaV3 | SchemaV4): void;
|
|
@@ -36,14 +37,12 @@ export declare abstract class Digester<S extends Schema<ET, CT>, ET extends Enti
|
|
|
36
37
|
*/
|
|
37
38
|
protected abstract mapODataType(type: string): TypeModel;
|
|
38
39
|
digest(): Promise<DataModel>;
|
|
39
|
-
private collectModelTypes;
|
|
40
40
|
private digestEntityTypesAndOperations;
|
|
41
41
|
private getBaseModel;
|
|
42
42
|
private addTypeDefinition;
|
|
43
43
|
private addComplexType;
|
|
44
44
|
private addEntityType;
|
|
45
45
|
private postProcessModel;
|
|
46
|
-
private sortModelsByInheritance;
|
|
47
46
|
private collectBaseClassPropsAndKeys;
|
|
48
47
|
protected mapProp: (p: Property, entityPropConfig?: PropertyGenerationOptions | undefined) => PropertyModel;
|
|
49
48
|
}
|
|
@@ -15,14 +15,15 @@ class Digester {
|
|
|
15
15
|
if (!p.$.Type) {
|
|
16
16
|
throw new Error(`No type information given for property [${p.$.Name}]!`);
|
|
17
17
|
}
|
|
18
|
-
const configProp = this.serviceConfigHelper.
|
|
18
|
+
const configProp = this.serviceConfigHelper.findPropConfigByName(p.$.Name);
|
|
19
19
|
const name = this.namingHelper.getModelPropName((entityPropConfig === null || entityPropConfig === void 0 ? void 0 : entityPropConfig.mappedName) || (configProp === null || configProp === void 0 ? void 0 : configProp.mappedName) || p.$.Name);
|
|
20
20
|
const isCollection = !!p.$.Type.match(/^Collection\(/);
|
|
21
21
|
let dataType = p.$.Type.replace(/^Collection\(([^\)]+)\)/, "$1");
|
|
22
|
+
// support for primitive type mapping
|
|
22
23
|
if (this.namingHelper.includesServicePrefix(dataType)) {
|
|
23
|
-
const
|
|
24
|
-
if (
|
|
25
|
-
dataType =
|
|
24
|
+
const dt = this.dataModel.getPrimitiveType(dataType);
|
|
25
|
+
if (dt !== undefined) {
|
|
26
|
+
dataType = dt;
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
let result;
|
|
@@ -31,7 +32,7 @@ class Digester {
|
|
|
31
32
|
if (this.namingHelper.includesServicePrefix(dataType)) {
|
|
32
33
|
const resultDt = this.model2Type.get(dataType);
|
|
33
34
|
if (!resultDt) {
|
|
34
|
-
throw new Error(`Couldn't determine model type for data type
|
|
35
|
+
throw new Error(`Couldn't determine model data type for property "${p.$.Name}"! Given data type: "${dataType}".`);
|
|
35
36
|
}
|
|
36
37
|
// special handling for enums
|
|
37
38
|
if (resultDt === "EnumType" /* DataTypes.EnumType */) {
|
|
@@ -72,113 +73,122 @@ class Digester {
|
|
|
72
73
|
else {
|
|
73
74
|
throw new Error(`Unknown type [${dataType}]: Not 'Collection(...)', not OData type 'Edm.*', not starting with one of the namespaces!W`);
|
|
74
75
|
}
|
|
75
|
-
return Object.assign({ odataName: p.$.Name, name, odataType: p.$.Type, required: p.$.Nullable === "false", isCollection: isCollection, managed: typeof (entityPropConfig === null || entityPropConfig === void 0 ? void 0 : entityPropConfig.managed) !== "undefined" ? entityPropConfig.managed : configProp === null || configProp === void 0 ? void 0 : configProp.managed }, result);
|
|
76
|
+
return Object.assign({ odataName: p.$.Name, name, odataType: p.$.Type, fqType: dataType, required: p.$.Nullable === "false", isCollection: isCollection, managed: typeof (entityPropConfig === null || entityPropConfig === void 0 ? void 0 : entityPropConfig.managed) !== "undefined" ? entityPropConfig.managed : configProp === null || configProp === void 0 ? void 0 : configProp.managed }, result);
|
|
76
77
|
};
|
|
77
|
-
|
|
78
|
+
const namespaces = schemas.map((s) => [s.$.Namespace, s.$.Alias]);
|
|
79
|
+
this.dataModel = new DataModel_1.DataModel(namespaces, version, converters);
|
|
78
80
|
this.serviceConfigHelper = new ServiceConfigHelper_1.ServiceConfigHelper(options);
|
|
79
81
|
this.collectModelTypes(schemas);
|
|
80
82
|
}
|
|
81
|
-
digest() {
|
|
82
|
-
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
83
|
-
this.digestEntityTypesAndOperations();
|
|
84
|
-
// delegate to version specific entity container digestion
|
|
85
|
-
this.schemas.forEach((schema) => this.digestEntityContainer(schema));
|
|
86
|
-
return this.dataModel;
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
83
|
collectModelTypes(schemas) {
|
|
90
84
|
schemas.forEach((schema) => {
|
|
91
85
|
var _a, _b, _c;
|
|
92
|
-
const
|
|
86
|
+
const { Namespace: ns, Alias: alias } = schema.$;
|
|
93
87
|
(_a = schema.EnumType) === null || _a === void 0 ? void 0 : _a.forEach((et) => {
|
|
94
|
-
this.
|
|
88
|
+
this.addModel2Type(ns, alias, et.$.Name, "EnumType" /* DataTypes.EnumType */);
|
|
95
89
|
});
|
|
96
90
|
(_b = schema.ComplexType) === null || _b === void 0 ? void 0 : _b.forEach((ct) => {
|
|
97
|
-
this.
|
|
91
|
+
this.addModel2Type(ns, alias, ct.$.Name, "ComplexType" /* DataTypes.ComplexType */);
|
|
98
92
|
});
|
|
99
93
|
(_c = schema.EntityType) === null || _c === void 0 ? void 0 : _c.forEach((et) => {
|
|
100
|
-
this.
|
|
94
|
+
this.addModel2Type(ns, alias, et.$.Name, "ModelType" /* DataTypes.ModelType */);
|
|
101
95
|
});
|
|
102
96
|
});
|
|
103
97
|
}
|
|
98
|
+
addModel2Type(ns, alias, name, dt) {
|
|
99
|
+
this.model2Type.set((0, DataModel_1.withNamespace)(ns, name), dt);
|
|
100
|
+
if (alias) {
|
|
101
|
+
this.model2Type.set((0, DataModel_1.withNamespace)(alias, name), dt);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
digest() {
|
|
105
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
106
|
+
this.digestEntityTypesAndOperations();
|
|
107
|
+
// delegate to version specific entity container digestion
|
|
108
|
+
this.schemas.forEach((schema) => this.digestEntityContainer(schema));
|
|
109
|
+
return this.dataModel;
|
|
110
|
+
});
|
|
111
|
+
}
|
|
104
112
|
digestEntityTypesAndOperations() {
|
|
105
113
|
this.schemas.forEach((schema) => {
|
|
114
|
+
const ns = [schema.$.Namespace, schema.$.Alias];
|
|
106
115
|
// type definitions: alias for primitive types
|
|
107
|
-
this.addTypeDefinition(schema.TypeDefinition);
|
|
116
|
+
this.addTypeDefinition(schema.$.Namespace, schema.TypeDefinition);
|
|
108
117
|
// enums
|
|
109
118
|
if (schema.EnumType) {
|
|
110
119
|
for (const et of schema.EnumType) {
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
120
|
+
const odataName = et.$.Name;
|
|
121
|
+
const fqName = (0, DataModel_1.withNamespace)(ns[0], odataName);
|
|
122
|
+
this.dataModel.addEnum(ns[0], odataName, {
|
|
123
|
+
fqName,
|
|
124
|
+
odataName,
|
|
125
|
+
name: this.namingHelper.getEnumName(odataName),
|
|
115
126
|
members: et.Member.map((m) => m.$.Name),
|
|
116
127
|
});
|
|
117
128
|
}
|
|
118
129
|
}
|
|
119
|
-
// entity types
|
|
120
|
-
this.addEntityType(schema.EntityType);
|
|
121
130
|
// complex types
|
|
122
|
-
this.addComplexType(schema.ComplexType);
|
|
131
|
+
this.addComplexType(ns, schema.ComplexType);
|
|
132
|
+
// entity types
|
|
133
|
+
this.addEntityType(ns, schema.EntityType);
|
|
123
134
|
// V4 only: function & action types
|
|
124
135
|
this.digestOperations(schema);
|
|
125
136
|
});
|
|
126
137
|
this.postProcessModel();
|
|
127
138
|
}
|
|
128
|
-
getBaseModel(model) {
|
|
139
|
+
getBaseModel(namespace, model) {
|
|
129
140
|
var _a;
|
|
130
|
-
const entityConfig = this.serviceConfigHelper.findConfigEntityByName(model.$.Name);
|
|
131
|
-
const entityName = (entityConfig === null || entityConfig === void 0 ? void 0 : entityConfig.mappedName) || model.$.Name;
|
|
132
|
-
const name = this.namingHelper.getModelName(entityName);
|
|
133
|
-
const qName = this.namingHelper.getQName(entityName);
|
|
134
|
-
const editableName = this.namingHelper.getEditableModelName(entityName);
|
|
135
141
|
const odataName = model.$.Name;
|
|
136
|
-
const
|
|
137
|
-
const
|
|
142
|
+
const fqName = (0, DataModel_1.withNamespace)(namespace[0], odataName);
|
|
143
|
+
const entityConfig = this.serviceConfigHelper.findEntityConfigByName(namespace, odataName);
|
|
144
|
+
const entityName = (entityConfig === null || entityConfig === void 0 ? void 0 : entityConfig.mappedName) || model.$.Name;
|
|
145
|
+
// map properties respecting the config
|
|
146
|
+
const props = [...((_a = model.Property) !== null && _a !== void 0 ? _a : []), ...this.getNavigationProps(model)].map((p) => {
|
|
147
|
+
var _a;
|
|
148
|
+
const epConfig = (_a = entityConfig === null || entityConfig === void 0 ? void 0 : entityConfig.properties) === null || _a === void 0 ? void 0 : _a.find((ep) => ep.name === p.$.Name);
|
|
149
|
+
return this.mapProp(p, epConfig);
|
|
150
|
+
});
|
|
138
151
|
// support for base types, i.e. extends clause of interfaces
|
|
139
152
|
const baseClasses = [];
|
|
140
|
-
if (
|
|
141
|
-
baseClasses.push(
|
|
153
|
+
if (model.$.BaseType) {
|
|
154
|
+
baseClasses.push(model.$.BaseType);
|
|
142
155
|
}
|
|
143
156
|
return {
|
|
144
|
-
|
|
145
|
-
qName,
|
|
157
|
+
fqName,
|
|
146
158
|
odataName,
|
|
147
|
-
|
|
159
|
+
name: this.namingHelper.getModelName(entityName),
|
|
160
|
+
qName: this.namingHelper.getQName(entityName),
|
|
161
|
+
editableName: this.namingHelper.getEditableModelName(entityName),
|
|
148
162
|
baseClasses,
|
|
149
|
-
props
|
|
150
|
-
var _a;
|
|
151
|
-
const epConfig = (_a = entityConfig === null || entityConfig === void 0 ? void 0 : entityConfig.properties) === null || _a === void 0 ? void 0 : _a.find((ep) => ep.name === p.$.Name);
|
|
152
|
-
return this.mapProp(p, epConfig);
|
|
153
|
-
}),
|
|
163
|
+
props,
|
|
154
164
|
baseProps: [], // postprocess required
|
|
155
165
|
};
|
|
156
166
|
}
|
|
157
|
-
addTypeDefinition(types) {
|
|
167
|
+
addTypeDefinition(ns, types) {
|
|
158
168
|
if (!types || !types.length) {
|
|
159
169
|
return;
|
|
160
170
|
}
|
|
161
171
|
for (const t of types) {
|
|
162
|
-
this.dataModel.addTypeDefinition(t.$.Name, t.$.UnderlyingType);
|
|
172
|
+
this.dataModel.addTypeDefinition(ns, t.$.Name, t.$.UnderlyingType);
|
|
163
173
|
}
|
|
164
174
|
}
|
|
165
|
-
addComplexType(models) {
|
|
175
|
+
addComplexType(namespace, models) {
|
|
166
176
|
if (!models || !models.length) {
|
|
167
177
|
return;
|
|
168
178
|
}
|
|
169
179
|
for (const model of models) {
|
|
170
|
-
const baseModel = this.getBaseModel(model);
|
|
171
|
-
this.dataModel.addComplexType(baseModel.
|
|
180
|
+
const baseModel = this.getBaseModel(namespace, model);
|
|
181
|
+
this.dataModel.addComplexType(namespace[0], baseModel.odataName, baseModel);
|
|
172
182
|
}
|
|
173
183
|
}
|
|
174
|
-
addEntityType(models) {
|
|
184
|
+
addEntityType(namespace, models) {
|
|
175
185
|
var _a;
|
|
176
186
|
if (!models || !models.length) {
|
|
177
187
|
return;
|
|
178
188
|
}
|
|
179
189
|
for (const model of models) {
|
|
180
|
-
const baseModel = this.getBaseModel(model);
|
|
181
|
-
const entityConfig = this.serviceConfigHelper.
|
|
190
|
+
const baseModel = this.getBaseModel(namespace, model);
|
|
191
|
+
const entityConfig = this.serviceConfigHelper.findEntityConfigByName(namespace, model.$.Name);
|
|
182
192
|
const entityName = (entityConfig === null || entityConfig === void 0 ? void 0 : entityConfig.mappedName) || model.$.Name;
|
|
183
193
|
// key support: we add keys from this entity,
|
|
184
194
|
// but not keys stemming from base classes (postprocess required)
|
|
@@ -193,7 +203,7 @@ class Digester {
|
|
|
193
203
|
keyNames.push(...propNames);
|
|
194
204
|
}
|
|
195
205
|
}
|
|
196
|
-
this.dataModel.
|
|
206
|
+
this.dataModel.addEntityType(namespace[0], baseModel.odataName, Object.assign(Object.assign({}, baseModel), { idModelName: this.namingHelper.getIdModelName(entityName), qIdFunctionName: this.namingHelper.getQIdFunctionName(entityName), generateId: true, keyNames: keyNames, keys: [], getKeyUnion: () => keyNames.join(" | ") }));
|
|
197
207
|
}
|
|
198
208
|
}
|
|
199
209
|
postProcessModel() {
|
|
@@ -203,8 +213,8 @@ class Digester {
|
|
|
203
213
|
const [baseProps] = this.collectBaseClassPropsAndKeys(model, []);
|
|
204
214
|
model.baseProps = baseProps;
|
|
205
215
|
});
|
|
206
|
-
const modelTypes = this.dataModel.getModels();
|
|
207
216
|
// entity types
|
|
217
|
+
const modelTypes = this.dataModel.getEntityTypes();
|
|
208
218
|
modelTypes.forEach((model) => {
|
|
209
219
|
const [baseProps, baseKeys, idName, qIdName] = this.collectBaseClassPropsAndKeys(model, []);
|
|
210
220
|
model.baseProps = baseProps;
|
|
@@ -232,47 +242,15 @@ class Digester {
|
|
|
232
242
|
return prop;
|
|
233
243
|
});
|
|
234
244
|
});
|
|
235
|
-
const sortedModelTypes = this.sortModelsByInheritance(modelTypes);
|
|
236
|
-
this.dataModel.setModels(sortedModelTypes);
|
|
237
|
-
const sortedComplexTypes = this.sortModelsByInheritance(complexTypes);
|
|
238
|
-
this.dataModel.setComplexTypes(sortedComplexTypes);
|
|
239
|
-
}
|
|
240
|
-
sortModelsByInheritance(models) {
|
|
241
|
-
// recursively visit all models and sort them by inheritance such that base classes
|
|
242
|
-
// are always before derived classes
|
|
243
|
-
const sortedModels = {};
|
|
244
|
-
const visitedModels = new Set();
|
|
245
|
-
const inProgressModels = new Set();
|
|
246
|
-
function visit(model) {
|
|
247
|
-
if (inProgressModels.has(model)) {
|
|
248
|
-
throw new Error("Cyclic dependencies detected!");
|
|
249
|
-
}
|
|
250
|
-
if (!visitedModels.has(model)) {
|
|
251
|
-
inProgressModels.add(model);
|
|
252
|
-
for (const baseClassName of model.baseClasses) {
|
|
253
|
-
const baseClass = models.find((e) => e.name === baseClassName);
|
|
254
|
-
if (baseClass) {
|
|
255
|
-
visit(baseClass);
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
visitedModels.add(model);
|
|
259
|
-
inProgressModels.delete(model);
|
|
260
|
-
sortedModels[model.name] = model;
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
for (const model of models) {
|
|
264
|
-
visit(model);
|
|
265
|
-
}
|
|
266
|
-
return sortedModels;
|
|
267
245
|
}
|
|
268
246
|
collectBaseClassPropsAndKeys(model, visitedModels) {
|
|
269
|
-
if (visitedModels.includes(model.
|
|
270
|
-
throw new Error(`Cyclic inheritance detected for model ${model.
|
|
247
|
+
if (visitedModels.includes(model.fqName)) {
|
|
248
|
+
throw new Error(`Cyclic inheritance detected for model ${model.fqName}!`);
|
|
271
249
|
}
|
|
272
|
-
visitedModels.push(model.
|
|
250
|
+
visitedModels.push(model.fqName);
|
|
273
251
|
return model.baseClasses.reduce(([props, keys, idName, qIdName], bc) => {
|
|
274
252
|
var _a;
|
|
275
|
-
const baseModel = this.dataModel.
|
|
253
|
+
const baseModel = this.dataModel.getEntityType(bc) || this.dataModel.getComplexType(bc);
|
|
276
254
|
if (!baseModel) {
|
|
277
255
|
throw new Error(`BaseModel "${bc}" doesn't exist!`);
|
|
278
256
|
}
|
|
@@ -289,10 +267,11 @@ class Digester {
|
|
|
289
267
|
}
|
|
290
268
|
}
|
|
291
269
|
props.push(...baseModel.props);
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
270
|
+
const entityModel = baseModel;
|
|
271
|
+
if ((_a = entityModel.keyNames) === null || _a === void 0 ? void 0 : _a.length) {
|
|
272
|
+
keys.push(...entityModel.keyNames.filter((kn) => !keys.includes(kn)));
|
|
273
|
+
idNameResult = entityModel.idModelName;
|
|
274
|
+
qIdNameResult = entityModel.qIdFunctionName;
|
|
296
275
|
}
|
|
297
276
|
return [props, keys, idNameResult, qIdNameResult];
|
|
298
277
|
}, [[], [], "", ""]);
|
|
@@ -300,5 +279,4 @@ class Digester {
|
|
|
300
279
|
}
|
|
301
280
|
exports.Digester = Digester;
|
|
302
281
|
Digester.EDM_PREFIX = "Edm.";
|
|
303
|
-
Digester.ROOT_OPERATION = "/";
|
|
304
282
|
//# sourceMappingURL=DataModelDigestion.js.map
|